Loop through a list in Python using enumerate and openpyxl - python

New Python convert here. Simply, trying to loop through a list in Python using openpyxl. Of course, my list has about 100 items and my code has more conditions.
lst = ['1','2','a','a12']
for value in enumerate(lst):
row = ws1.iter_rows(min_row=value,max_row=value)
When I try without enumerate I get error "must be str, not int" and when I try with enumerate I get error "Can only concatenate tuple (not "int") to tuple".
I believe it has something to do with min_row and max_row requiring an int, but even then I get "'int' object is not iterable". Also, tried making value str() and int()
Any advice much appreciated, thank you.

When you wrap an iterable with enumerate, you get two values:
the index of enumeration
the value of the iterable at that index
That pair is emitted from enumerate() as a tuple.
You're only identifying one variable name, though, so value contains the whole tuple,
i.e. value = (i, current_val_of_lst).
Instead, try:
lst = ['1','2','a','a12']
for i, value in enumerate(lst):
# i is the enumeration index
# value is the entry in list
...

Related

With python How to get only the indices of list items and use them as a variable in f-string

I'm trying to get selenium to click specific buttons on a website.
To do that I need the indices of list items to be a variable in a f-string.
Is there a neat way to access the indices of that list and declare them a variable? I know you can get both values, index and itemvalue of a list by enumerate, but maybe theres another way than converting the index strings into integers and work on with these.
Thats what I got so far:
T3 = browser.find_elements_by_xpath("//*[#id='tabelle_merkliste']/tbody/tr[position()<25]/td[10]/img/following::td[2]")
verf3string = []
for i in T3: # retrieve textelement
print(i.text)
textelement = i.text.split('/')
plätze = textelement[0] # only retrieve first position of string
print(plätze)
verf3string.append(plätze) #safe text in list
print(verf3string)
for i in range(len(verf3string)): # converting string list into list of integers to be able to compare numbers by </>
verf3 = (verf3string[i])
print(verf3)
for i in (verf3):
if i > 0:
x = verf3.index(i)
browser.find_element_by_xpath(f'//*[#id="tabelle_merkliste"]/tbody/tr{x}/td{y}/img').click()
#this gives me the error TypeError: '>' not supported between instances of 'str' and 'int'
By Any help is appreciated, thanks!
By enumerate I meant using it to retrieve indeces. It gives me the index plus value.
for index, value in enumerate(test_list):
print(index, value)
(
You can just retrieve the index of the item in a list (called 'array' here) like this:
x = array.index(i)
Or just do it in the f-string:
f'//*[#id="tabelle_merkliste"]/tbody/tr{array.index(i)}/td{y} /img'

Problem with comparing two items in a list of lists

I have this list
zipped_values = [(3.0, 4.242640687119285), (3.605551275463989, 3.1622776601683795), (5.0, 3.1622776601683795), (4.123105625617661, 4.47213595499958), (5.0, 4.0), (5.830951894845301, 7.810249675906654), (5.0990195135927845, 5.385164807134504), (7.0710678118654755, 8.06225774829855), (7.0710678118654755, 7.280109889280518), (8.06225774829855, 8.246211251235321)]
what I am trying to do is compare each item within the lists to each other (within the same list), to find out what the minimum is. In the first case, it would be 3.0, in the second, it would be 3.1.
Now what I am trying to do is, if the minimum is the first element, assign that element (3.0) to a dictionary key named M1, and if the minimum is the second element, assign that element to a dictionary key named M2.
This is what I've come up with:
for jk in zipped_value:
for n in jk:
if zipped_value[0][n] < zipped_value[0][n+1]:
dictionary["M1"].append(zipped_value[0][n])
But it gives me this error: TypeError: tuple indices must be integers or slices, not float
What do I do?
You don't need the inner loop. jk is the tuple, you just need to compare jk[0] with jk[1]. You can simplify this by unpacking to two variables when looping.
for a, b in zipped_values:
if a < b:
dictionary["M1"].append(a)
else:
dictionary["M2"].append(b)
Your inner for loop is iterating over the tuple, so the value of n is actually the floats in your tuple. Additionally, you will have problems with the append statement since it does not seem like you are initializing the dictionary values to be list type. Lastly, python allows you to unpack your tuples as you are iterative over them, making the code easier to read and comprehend rather than needing to use indices.
Try this:
from collections import defaultdict
dictionary = defaultdict(list)
for item1, item2 in zipped_value:
if item1 < item2:
dictionary["M1"].append(item1)
else:
dictionary["M2"].append(item2)
You are getting this error "TypeError: tuple indices must be integers or slices, not float" because in the
"for n in jk" the 'n' here is actually representing the float values in tuples and is not the index of tuple.
So,
if zipped_value[0][n] < zipped_value[0][n+1]:
dictionary["M1"].append(zipped_value[0][n])
is not correct indexing to access elements of tuples in a list.
You can modify your code to something below to get correct results:
for jk in zipped_values:
if jk[0] < jk[1]:
dictionary["M1"].append(jk[0])
else:
dictionary["M2"].append(jk[1])

summing dict value of list to single integer

I am trying to do something pretty simple but cant seem to get it. I have a dictionary where the value is a list. I am trying to just sum the list and assign the value back to the same key as an int. Using the code below the first line doesn't do anything, the second as it says puts the value back but in a list. All other things ive tried has given me an error can only assign iterable. As far as i know iterables are anything that can be iterated on such as list and not int. Why can I only use iterable and how can i fix this issue ? The dict im using is here (https://gist.github.com/ishikawa-rei/53c100449605e370ef66f1c06f15b62e)
for i in dict.values():
i = sum(i)
#i[:] = [sum(i) / 3600] # puts answer into dict but as a list
You can use simple dictionary comprehension if your dict values are all lists
{k:sum(v) for k, v in dict.items()}
for i in dikt.keys():
dickt[i] = sum(dict[i]))
btw, dict is a type. best not to use it as a variable name

Lists in a list

I am quite new to Python. I have a list containing some more lists, but only in two dimension (e.g. List[a][b]). Now for every value [a] I want to access a certain value [b] (10 in this case). For now it would be sufficent to just print every value List[a][10]. I tried:
for rec in List:
print List[rec][10]
That gives me the error "TypeError: list indices must be integers, not list". However if I just try "print List[0][10]" it gives me the value I want. In my for-Loop isn't rec an integer? How could I solve this problem?
Additional info: I am using Python 2.4.3 to be able to use the shapefile library that lets me access GIS data (my list).
for rec in List:
print rec[10]
should work.
You need to use:
for rec in List:
print rec[10]
or
for i range(len(List)):
print List[i][10]
rec in your case is not an integer, it is the first item of list. For you to use it as an integer you must add range in the for loop, like "for rec in range(0,len(List))"

Append select dict keys to a list [duplicate]

I am trying to append objects to the end of a list repeatedly, like so:
list1 = []
n = 3
for i in range(0, n):
list1 = list1.append([i])
But I get an error like: AttributeError: 'NoneType' object has no attribute 'append'. Is this because list1 starts off as an empty list? How do I fix this error?
This question is specifically about how to fix the problem and append to the list correctly. In the original code, the reported error occurs when using a loop because .append returns None the first time. For why None is returned (the underlying design decision), see Why do these list operations return None, rather than the resulting list?.
If you have an IndexError from trying to assign to an index just past the end of a list - that doesn't work; you need the .append method instead. For more information, see Why does this iterative list-growing code give IndexError: list assignment index out of range? How can I repeatedly add elements to a list?.
If you want to append the same value multiple times, see Python: Append item to list N times.
append actually changes the list. Also, it takes an item, not a list. Hence, all you need is
for i in range(n):
list1.append(i)
(By the way, note that you can use range(n), in this case.)
I assume your actual use is more complicated, but you may be able to use a list comprehension, which is more pythonic for this:
list1 = [i for i in range(n)]
Or, in this case, in Python 2.x range(n) in fact creates the list that you want already, although in Python 3.x, you need list(range(n)).
You don't need the assignment operator. append returns None.
append returns None, so at the second iteration you are calling method append of NoneType. Just remove the assignment:
for i in range(0, n):
list1.append([i])
Mikola has the right answer but a little more explanation. It will run the first time, but because append returns None, after the first iteration of the for loop, your assignment will cause list1 to equal None and therefore the error is thrown on the second iteration.
I personally prefer the + operator than append:
for i in range(0, n):
list1 += [[i]]
But this is creating a new list every time, so might not be the best if performance is critical.
Note that you also can use insert in order to put number into the required position within list:
initList = [1,2,3,4,5]
initList.insert(2, 10) # insert(pos, val) => initList = [1,2,10,3,4,5]
And also note that in python you can always get a list length using method len()
Like Mikola said, append() returns a void, so every iteration you're setting list1 to a nonetype because append is returning a nonetype. On the next iteration, list1 is null so you're trying to call the append method of a null. Nulls don't have methods, hence your error.
use my_list.append(...)
and do not use and other list to append as list are mutable.

Categories

Resources