# 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:** 1

<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:** [February 28, 2022, 3:12pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/1 "2022-02-28T15:12:54Z")

</div>

This top post is additional context.

I want to rewrite a huge script.

This first part I was able to figure out with help from community members, in resources listed at the bottom of this post, to get this far. I anticipate that I will need help though, and I will want to reference this later.

First a bunch of reads  
The machines are numbered 1-18 and sometimes 15th is just null or not connected, no 13, and 1-9 written as 01-09  
example of what was  
`Machine1gross=system.tag.read("[Facility]folder/subgroup/M01/M01Production/M01Gross")`

So I think this becomes like:

```auto
numMachinesWith0=9
pathGross=
["Facility]folder/subgroup/M0{}/M0{}Production/M0{}Gross".format(nineSet,nineSet,nineSet) for nineSet in range(1,numMachinesWith0+1)]

```

it is alive

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/a/6/a6e2fe8f3daae85f1410eaca755b4cd10b0a5f60.png)

* * *

references for convenience

```auto
numComments = 14
pathsComments = ["[Test]SomeTagPath/Comment{}".format(path) for path in range(1,numComments + 1)]
value14Spaces = ["space"]*numComments

for c in range(numComments):
    print "commentPath: ",pathsComments[c], " ","value:" , value14Spaces[c]

```

[Python guide for list comprehensions](https://www.pythonforbeginners.com/basics/list-comprehensions-in-python)

[list comprehensions w3 schools](https://www.w3schools.com/python/python_lists_comprehension.asp)

[https://forum.inductiveautomation.com/t/tag-writeblocking-multiple-tags-to-one-value](https://forum.inductiveautomation.com/t/tag-writeblocking-multiple-tags-to-one-value)

---

<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:** [February 28, 2022, 3:14pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/2 "2022-02-28T15:14:20Z")

</div>

Right now I am doing a list comprehension for 1-9  
and I plan to do another for 10-18  
however I am looking up how to say like not 13

Is it best to do these in parts?

and I wonder what will happen to my script if 15 doesn’t exist sometimes  
Will my script fail if a path results in null or a bad expression tag?

---

<div class="post-metadata">

**Author:** ![witman](https://avatars.discourse-cdn.com/v4/letter/w/d2c977/32.png) [@witman](https://forum.inductiveautomation.com/u/witman)\
**Post date:** [February 28, 2022, 3:22pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/3 "2022-02-28T15:22:05Z")

</div>

You can easily exclude items from a list comprehension like this:

```python
exclusions = [13,15]
print [x for x in range(1,17) if x not in exclusions]

```

```python
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16]

```

---

<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:** [February 28, 2022, 3:24pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/4 "2022-02-28T15:24:49Z")

</div>

what about the 0?

01, 02, …09  
10, 11, …18

---

<div class="post-metadata">

**Author:** ![witman](https://avatars.discourse-cdn.com/v4/letter/w/d2c977/32.png) [@witman](https://forum.inductiveautomation.com/u/witman)\
**Post date:** [February 28, 2022, 3:28pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/5 "2022-02-28T15:28:51Z")

</div>

```auto
exclusions = [13,15]
numbers = [x for x in range(1,17) if x not in exclusions]
print ["tag{:0>2}".format(x) for x in numbers]

```

```auto
['tag01', 'tag02', 'tag03', 'tag04', 'tag05', 'tag06', 'tag07', 'tag08', 'tag09', 'tag10', 'tag11', 'tag12', 'tag14', 'tag16']

```

---

<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:** [February 28, 2022, 3:28pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/6 "2022-02-28T15:28:58Z")

</div>

Might want to do a little more research on `string.format()`

To add a leading 0 to decimal with less than 2 digits you can use:

```python
print ['path{:02d}'.format(path) for path in range(10)]

```

You can also use a number designation in the format so it becomes:

```python
print ['path{0:02d}'.format(path) for path in range(10)]

```

Combining that with what @witman has shown:

```python
numMachines = 18
exclusions = [13,15]
pathsGross = ['[Facility]folder/subgroup/M{0:02d}/M{0:02d}Production/M{0:02d}Gross'.format(nineSet) for nineSet in range(1,numMachines + 1) if nineSet not in exclusions]

```

---

<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:** [February 28, 2022, 4:35pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/7 "2022-02-28T16:35:54Z")

</div>

Thanks

I am reading about string.format()

[w3 schools string format](https://www.w3schools.com/python/ref_string_format.asp)

[gfg string formatting](https://www.geeksforgeeks.org/string-formatting-in-python/)

I am still reading this one, it is huge, but I have not seen notes on {0:02d} yet, so I am really happy you showed me it  
[gfg string format method](https://www.geeksforgeeks.org/python-string-format-method/)

---

<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:** [February 28, 2022, 4:51pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/8 "2022-02-28T16:51:03Z")

</div>

I don’t want to exclude 15

I know 15 will sometimes not be connected, so the tags will be bad

Can I just include it? Will reading a bad tag error the script?  
Or do I need to check if these values are all null before I do reads?

in some conditions, I will be writing these values to tags later in my script

---

<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:** [February 28, 2022, 5:16pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/9 "2022-02-28T17:16:38Z")

</div>

It won’t give you an error, but you should be able to check the quality of the tags after you read them.

---

<div class="post-metadata">

**Author:** ![andrews](https://avatars.discourse-cdn.com/v4/letter/a/898d66/32.png) [@andrews](https://forum.inductiveautomation.com/u/andrews)\
**Post date:** [February 28, 2022, 6:55pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/10 "2022-02-28T18:55:40Z")

</div>

On a side note because it has helped me a lot check out [Catalog Home | Codecademy](https://www.codecademy.com/learn) they have a decent amount of free lessons, editor + console to test and see live results. You learn by doing which I really like. they have tips and good instructions.

---

<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:** [February 28, 2022, 7:55pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/11 "2022-02-28T19:55:17Z")

</div>

I am trying to use \n to make a new line

the script console keeps typing \n as part of the string

I thought maybe this was Python in Ignition

Says that is it should work though.  
[https://docs.inductiveautomation.com/display/DOC81/Strings](https://docs.inductiveautomation.com/display/DOC81/Strings)

I am trying to edit this and upload an image. It is just spinning at 0%

```auto
test=["[this]M{0:02d}/M{0:02d}Production/M{0:02d}Gross\n".format(nineSet) 
for nineSet in range(1,numMachinesWith0+1)]
test

```

```auto
['[this]M01/M01Production/M01Gross\n', '[this]M02/M02Production/M02Gross\n', '[this]M03/M03Production/M03Gross\n',.....

```

---

<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:** [February 28, 2022, 8:02pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/12 "2022-02-28T20:02:04Z")

</div>

how are you trying to display it?

```python
s = '1\n2\n3'

s

print s

```

Output:

```nohighlight
'1\n2\n3'
1
2
3
>>>

```

---

<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:** [February 28, 2022, 8:04pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/13 "2022-02-28T20:04:44Z")

</div>

I edited above with poor timing. Sorry.  
I was trying to get a new line incorrectly.  
Thanks for your example

* * *

Your example gave me the idea

input

```auto
numMachinesWith0=18
test=["[this]M{0:02d}/M{0:02d}Production/M{0:02d}Gross".format(nineSet) 
for nineSet in range(0,numMachinesWith0+1)]
test[0]
test[1]
test[18]

```

output

```auto
'[this]M00/M00Production/M00Gross'
'[this]M01/M01Production/M01Gross'
'[this]M18/M18Production/M18Gross'

```

I think this is good because machine number is equal to the index number when reading.  
Maybe it is better to exclude 0 and 13. I have yet to see.

---

<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:** [February 28, 2022, 9:18pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/14 "2022-02-28T21:18:52Z")

</div>

This is why I recommend looking at the tag quality.  
In my example I have three tags, ‘Tag 01, Tag 02, and Tag 04’. The processing portion only pays attention to those qualities that are good.  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/6/d/6dd7a8361b2b54ad4f7077ed29dd67ddb90bce27.png)

```python
numberOfTags = 4
baseTagPath = '[Test]Tag {0:02d}'

tagPaths = [baseTagPath.format(i) for i in xrange(1, numberOfTags+1)]
valuesIn = system.tag.readBlocking(tagPaths)

print 'Tags In'
for tag, qVal in zip(tagPaths, valuesIn):
	print tag, ':', qVal

# Processing
tagsOut = []
valuesOut = []

for tag, qValue in zip(tagPaths, valuesIn):
	if 'Good' in str(qValue.quality):
		tagsOut.append(tag)
		valuesOut.append(qValue.value + 5)
		
print 'Tags Out'
for tag, val in zip(tagsOut, valuesOut):
	print tag, ':', val
numberOfTags = 4
baseTagPath = '[Test]Tag {0:02d}'

tagPaths = [baseTagPath.format(i) for i in xrange(1, numberOfTags+1)]
valuesIn = system.tag.readBlocking(tagPaths)

print 'Tags In'
for tag, qVal in zip(tagPaths, valuesIn):
	print tag, ':', qVal

# Processing
tagsOut = []
valuesOut = []
for tag, qValue in zip(tagPaths, valuesIn):
	if 'Good' in str(qValue.quality):
		tagsOut.append(tag)
		valuesOut.append(qValue.value + 5)
print '\n-----------\n\nTags Out'		
for tag, val in zip(tagsOut, valuesOut):
	print tag, ':', val

```

Output

```nohighlight
>>> 
Tags In
[Test]Tag 01 : [10, Good, Mon Feb 28 15:11:26 EST 2022 (1646079086152)]
[Test]Tag 02 : [20, Good, Mon Feb 28 15:11:28 EST 2022 (1646079088784)]
[Test]Tag 03 : [null, Bad_NotFound("Path '[Test]Tag 03' not found."), Wed Feb 16 12:47:37 EST 2022 (1645033657329)]
[Test]Tag 04 : [40, Good, Mon Feb 28 16:05:57 EST 2022 (1646082357934)]

-----------

Tags Out
[Test]Tag 01 : 15
[Test]Tag 02 : 25
[Test]Tag 04 : 45
>>> 

```

---

<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:** [February 28, 2022, 9:33pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/15 "2022-02-28T21:33:49Z")

</div>

Thanks for showing how the tag quality check can help.  
I appreciate it.

---

<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:** [February 28, 2022, 9:44pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/16 "2022-02-28T21:44:34Z")

</div>

> [@zacharyw.larson](#):
>
> `range(0,numMachinesWith0+1)`

Should note, that you don't need the `0` in `range()`. The start parameter is `0` by default.

```python

#range(start,stop,step)
# start - An integer number specifying at which position to start. Default is 0 (optional)
# stop - An integer runber specifying at which position to stop. Stop is not included in the returned set.
# step - An integer number specifying the incrementation. Default is 1 (optional)

print range(10)
print range(1,11)
print range(1,20,2)

```

Output

```auto
>>>
[0,1,2,3,4,5,6,7,8,9]
[1,2,3,4,5,6,7,8,9,10]
[1,3,5,7,11,13,15,17,19]
>>>

```

Sometimes we take the range syntax for granted, it isn't always straight forward all that you can accomplish with it.

Other examples of this are the `enumerate()` and `zip()` functions which are not used as often but can come in handy when you need it.

[https://docs.python.org/2.7/library/functions.html#enumerate](https://docs.python.org/2.7/library/functions.html#enumerate)  
[https://docs.python.org/2.7/library/functions.html#zip](https://docs.python.org/2.7/library/functions.html#zip)

---

<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:** [February 28, 2022, 10:03pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/17 "2022-02-28T22:03:47Z")

</div>

Thanks  
I like to say (0,variable+1) for the moment.

I am reading again about the tag provider and tag browser too.  
I am building a ship in a bottle without the config access so that nothing I do impacts other hubs.  
I really appreciate the tag provider made in the example.

I have a silly question that I am not sure how to look up.  
If a script runs once very 50 seconds as a gateway timer script, what is the best way to instead just run it at certain times like at the end of a shift and an hour after the end of a shift?

---

<div class="post-metadata">

**Author:** ![cmallonee](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/cmallonee/32/6416_2.png) [@cmallonee](https://forum.inductiveautomation.com/u/cmallonee)\
**Post date:** [February 28, 2022, 10:52pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/18 "2022-02-28T22:52:18Z")

</div>

Look into [Gateway Scheduled Scripts](https://docs.inductiveautomation.com/display/DOC81/Gateway+Event+Scripts#:~:text=Watch%20the%20Video-,Gateway%20Scheduled%20Scripts,-The%20following%20feature).

---

<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:** [March 1, 2022, 1:42pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/19 "2022-03-01T13:42:37Z")

</div>

8.1.0 unfortunately

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/0/8/08d14e6ad551b95a3ba770cf0e29281ca81a62bf.png)

---

<div class="post-metadata">

**Author:** ![dkhayes117](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/dkhayes117/32/68344_2.png) [@dkhayes117](https://forum.inductiveautomation.com/u/dkhayes117)\
**Post date:** [March 1, 2022, 1:44pm UTC](https://forum.inductiveautomation.com/t/python-list-comprehensions-help/56621/20 "2022-03-01T13:44:31Z")

</div>

I would definitely update to 8.1.14 if at all possible

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