# Python List Comprehensions Help

**URL:** <https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621>\
**Category:** Ignition\
**Created:** [February 28, 2022, 3:12pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621 "2022-02-28T15:12:54Z")\
**Posts on this page:** 20\
**Page:** 6

<div class="post-metadata">

**Author:** ![zacharyw.larson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zacharyw.larson/32/23749_2.png) [@zacharyw.larson](https://forum.inductiveautomation.com/u/zacharyw.larson)\
**Post date:** [June 1, 2022, 4:06pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/101 "2022-06-01T16:06:11Z")

</div>

101 posts now  
What should I mark as the solution?  
I should mark one and ask even similar questions in other threads?

So many solutions, highlighting comments:  
5, 16, 14, 40, 49, 67 , 71  
+/- 1 as I don’t really know how comments are counted.

I don’t understand comment 57 by Jordan, the dictionary is complex and I did not follow how it worked.  
Even with the post linked to using the nested dictionaries, I’m still not sure.

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [June 2, 2022, 5:31am UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/102 "2022-06-02T05:31:21Z")

</div>

> [@zacharyw.larson](#):
>
> +/- 1 as I don’t really know how comments are counted.

The url should tell you the id of the highest VISIBLE comment (it updates automatically as you scroll)  
Unrelated but I find it quite cool.

---

<div class="post-metadata">

**Author:** ![zacharyw.larson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zacharyw.larson/32/23749_2.png) [@zacharyw.larson](https://forum.inductiveautomation.com/u/zacharyw.larson)\
**Post date:** [July 14, 2022, 2:18pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/103 "2022-07-14T14:18:10Z")

</div>

Thanks again for so much help

`excludedDates=[x for x in theSixtyDates if x not in datesFromQuery]`

I was able to produce this code today.

---

<div class="post-metadata">

**Author:** ![zacharyw.larson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zacharyw.larson/32/23749_2.png) [@zacharyw.larson](https://forum.inductiveautomation.com/u/zacharyw.larson)\
**Post date:** [July 26, 2022, 2:23pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/104 "2022-07-26T14:23:23Z")

</div>

I got stuck yesterday with a custom property that I bound to a tag history.  
My ugly code workaround:

```auto
value=(currentVal[0][1])+(currentVal[0][6])+(currentVal[0][11])+(currentVal[0][16])+(currentVal[0][21])+(currentVal[0][26])+(currentVal[0][31])+(currentVal[0][36])+(currentVal[0][41])+(currentVal[0][46])+(currentVal[0][51])+(currentVal[0][56])+(currentVal[0][61])+(currentVal[0][66])

```

I got every 5th

```auto
x=range(71)
grossIndexes=x[1::5]

```

I just finished reading the thread over again to see if I could figure it out.  
I have checked sites online

```auto
y=[[1,2],[3,4],[5,6],[1,1]]
print y[0][1]

```

How do I make something like currentVal in the script console for testing?  
currentVal has 1 row, and 71 columns that start with one timestamp.

How would I pythonically sum and iterate through the currentVal columns?

---

<div class="post-metadata">

**Author:** ![JordanCClark](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jordancclark/32/83362_2.png) [@JordanCClark](https://forum.inductiveautomation.com/u/JordanCClark)\
**Post date:** [July 26, 2022, 3:11pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/105 "2022-07-26T15:11:56Z")

</div>

You’re very close. 🙂  
Based on what you have, I’m assuming this is a PyDataSet. Let me know if I’m off.

```python
x = range(71)

# Mock up some values
headers = ['col{}'.format(idx) for idx in x]
data = [[100 + idx for idx in x]]

# Make a dataset and a PyDataSet to play with
datasetIn = system.dataset.toDataSet(headers, data)
currentVal = system.dataset.toPyDataSet(datasetIn)

# You figured how to get every fifth starting with 1
grossIndexes=x[1::5]

# You can do the same thing with currentVal
grossValues = currentVal[0][1::5]

#Or, to sum it all up in one go
summedVal = sum(currentVal[0][1::5])
 
print grossValues
print summedVal

```

---

<div class="post-metadata">

**Author:** ![zacharyw.larson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zacharyw.larson/32/23749_2.png) [@zacharyw.larson](https://forum.inductiveautomation.com/u/zacharyw.larson)\
**Post date:** [July 26, 2022, 3:24pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/106 "2022-07-26T15:24:55Z")

</div>

> [@JordanCClark](#):
>
> `summedVal = sum(currentVal[0][1::5])`

Thank you, I am very upset I didn't realize this.

* * *

@JordanCClark  
I am doing something wrong in my testing.

input

```python
y=[[1,2],[3,4],[5,6],[1,1]]
sumY=sum(y[0][::2])
test =[y[0][::1]]
print sumY
print test

```

output

```python
1
[[1, 2]]

```

Oh I see, row 0 is [1,2]

---

<div class="post-metadata">

**Author:** ![JordanCClark](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jordancclark/32/83362_2.png) [@JordanCClark](https://forum.inductiveautomation.com/u/JordanCClark)\
**Post date:** [July 26, 2022, 3:49pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/107 "2022-07-26T15:49:18Z")

</div>

Just so I’m on the same page, your “first” post intimated data like `[[0,1,2,3,4,5,6,1,1]]`. If it’s really `[[1,2],[3,4],[5,6],[1,1]]`, then we’ll need to switch it up a bit. 🙂

---

<div class="post-metadata">

**Author:** ![zacharyw.larson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zacharyw.larson/32/23749_2.png) [@zacharyw.larson](https://forum.inductiveautomation.com/u/zacharyw.larson)\
**Post date:** [July 26, 2022, 3:51pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/108 "2022-07-26T15:51:53Z")

</div>

I am getting an error trying to upload an image of my test.

I am getting an error that says row sequence must be integer or string.

when I write  
`value=sum(currentVal[0][1::5])`

in my script on the pydataset currentVal.

---

<div class="post-metadata">

**Author:** ![JordanCClark](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jordancclark/32/83362_2.png) [@JordanCClark](https://forum.inductiveautomation.com/u/JordanCClark)\
**Post date:** [July 26, 2022, 3:59pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/109 "2022-07-26T15:59:17Z")

</div>

Oh, wait. You’re still at 8.1.0, right? No upgrade yet? There were later changes to make pyDataSets more friendly. I think you may have to coerce it to a list. Been a while since I’ve had to think about it. lol

Try something like:  
`print list(currentVal[0])`  
If it works, then put the slice after it.  
`value=sum(list(currentVal[0])[1::5])`

---

<div class="post-metadata">

**Author:** ![zacharyw.larson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zacharyw.larson/32/23749_2.png) [@zacharyw.larson](https://forum.inductiveautomation.com/u/zacharyw.larson)\
**Post date:** [July 26, 2022, 4:01pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/110 "2022-07-26T16:01:58Z")

</div>

> [@JordanCClark](#):
>
> value=sum(list(currentVal[0])[1::5])

why does `value=sum(list(currentVal[0])[1::5])`  
work?

I don't understand that at all. `currentVal[0]` isn't anything is it?  
I also don't know how to test print from a script I am running that isn't in the script console.

---

<div class="post-metadata">

**Author:** ![JordanCClark](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jordancclark/32/83362_2.png) [@JordanCClark](https://forum.inductiveautomation.com/u/JordanCClark)\
**Post date:** [July 26, 2022, 4:09pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/111 "2022-07-26T16:09:32Z")

</div>

That’s part of why changes were made. 😉

The datatype of the row is DatasetUtilities.PyDataSet.PyRow, which (IIRC) you could only reference from a single integer index or the column name. A slice, like `[1::5]`, was not allowed.  
_EDIT: It’s also why your ‘ugly’ code worked, because you were referencing individual elements._  
Turning the row into a list lets us be a bit more flexible.

If you’re in the designer, using print, or systyem.perspective.print() if you’re designing in Perspective will print to the designer console (Tools → Console).

---

<div class="post-metadata">

**Author:** ![zacharyw.larson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zacharyw.larson/32/23749_2.png) [@zacharyw.larson](https://forum.inductiveautomation.com/u/zacharyw.larson)\
**Post date:** [July 26, 2022, 5:04pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/112 "2022-07-26T17:04:42Z")

</div>

The other spot I got stuck a bit was in expression language.

Is it possible to benefit from list comprehensions in expression language?  
I had setup an expression tag. I don’t think there is a script tag, except working from one tag, to write to a memory tag.

Or in later versions, are there script tags?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 26, 2022, 5:12pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/113 "2022-07-26T17:12:34Z")

</div>

> [@zacharyw.larson](#):
>
> list comprehensions in expression language

No, expressions are not python. List comprehensions are part of the python language.

---

<div class="post-metadata">

**Author:** ![zacharyw.larson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zacharyw.larson/32/23749_2.png) [@zacharyw.larson](https://forum.inductiveautomation.com/u/zacharyw.larson)\
**Post date:** [August 16, 2022, 4:01pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/114 "2022-08-16T16:01:25Z")

</div>

```auto
currentVal = system.dataset.toPyDataSet(value)
net=list(currentVal[0])[2::5]
eff=list(currentVal[0])[5::5]
totals=[a/b for a,b in zip(net,eff)]

```

How do I work around the dividing by zero error?

```auto
net= [1, 2, 3, 0, 4]
eff =[.5, 0.75, 0, 1, 3]
totals=[(a)/(b) for a,b in zip(net,eff)]

```

I thought this would work:  
`totals=[a/b if b!=0 else 0 for a,b in zip(net,eff)]`  
I get nothing, and I am not sure why

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [August 16, 2022, 4:11pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/115 "2022-08-16T16:11:15Z")

</div>

> [@zacharyw.larson](#):
>
> ```auto
> net= [1, 2, 3, 0, 4]
> eff =[.5, 0.75, 0, 1, 3]
> totals=[(a)/(b) for a,b in zip(net,eff)]
> 
> ```

You can call custom functions in a list comprehension so maybe like

```auto
def divideHandleZero(a, b):
    try:
        return a/b
    except ZeroDivisionError:
        return 'some value you want when you divide by zero'

net= [1, 2, 3, 0, 4]
eff =[.5, 0.75, 0, 1, 3]
totals=[divideHandleZero(a, b) for a,b in zip(net,eff)]

```

---

<div class="post-metadata">

**Author:** ![zacharyw.larson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zacharyw.larson/32/23749_2.png) [@zacharyw.larson](https://forum.inductiveautomation.com/u/zacharyw.larson)\
**Post date:** [August 16, 2022, 4:13pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/116 "2022-08-16T16:13:12Z")

</div>

> [@zacharyw.larson](#):
>
> totals=[a/b if b!=0 else 0 for a,b in zip(net,eff)]

This worked, I forgot to type a print line.

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [August 16, 2022, 4:14pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/117 "2022-08-16T16:14:57Z")

</div>

Yea I was going to say say that should have worked.

That list comprehension is about the limit for me in terms of putting logic into a single line, if you need anything more complicated I’d recommend making a custom function and calling it inside your list comprehension. Especially if you think there may be other usages of it elsewhere in your program.

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [August 16, 2022, 4:22pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/118 "2022-08-16T16:22:52Z")

</div>

FYI, I think the _convention_ would be to write that like

```auto
totals = [a/b for a,b in zip(net,eff) if b != 0]

```

The reason is, because this more clearly shows what is being inserted into the list.

You could also do this, which some may think is less readable. `if b` will only return False if b is 0.

```auto
totals = [a/b for a,b in zip(net,eff) if b]

```

---

<div class="post-metadata">

**Author:** ![zacharyw.larson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/zacharyw.larson/32/23749_2.png) [@zacharyw.larson](https://forum.inductiveautomation.com/u/zacharyw.larson)\
**Post date:** [August 16, 2022, 4:25pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/119 "2022-08-16T16:25:37Z")

</div>

```auto
totals=[a/b for a,b in zip(net,eff) if b!=0 else 0]

```

This throws the error that ‘b’ is not defined.  
I usually see if statements at the end in other comprehensions people showed me though.

---

<div class="post-metadata">

**Author:** ![JordanCClark](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jordancclark/32/83362_2.png) [@JordanCClark](https://forum.inductiveautomation.com/u/JordanCClark)\
**Post date:** [August 16, 2022, 4:32pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/120 "2022-08-16T16:32:18Z")

</div>

if an else statement is needed, you’ll need to change up the order.

```auto
totals = [a/b if b != 0 else 0 for a,b in zip(net,eff)]

```

The difference is in the operation. An ‘if’ at the end checks after the calculation is done.  
EDIT2: Not completely sure on the overall operation, as removing the else at the end of the line gives all values where b != 0

EDIT: This might get to the edge of readability, though.

[Previous page](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621.md?page=5)

[Next page](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621.md?page=7)
