I have a very simple code where I want to loop through two lists at the same time. However, this gives me a ValueError: too many values to unpack.
def testing_something():
list1 = [1,2,3,4,45]
list2 = [1,4,4]
return list1, list2
for q,z in testing_something():
print (q,z)
The output of testing_something() is ([1, 2, 3, 4, 45], [1, 4, 4]), so I can imagine to be able to loop simultaneously through this output, with q in my case being [1, 2, 3, 4, 45] and z being [1,4,4]. Why does this raise a ValueError?
you can't use a single for to iterate over two lists at the same time. You should use zip function
def testing_something():
list1 = [1,2,3,4,45]
list2 = [1,4,4]
return list1, list2
for q,z in zip(testing_something()):
print(q)
print(z)
Note that zip will iterate until the lists have elements: if it finishes iterating over one, it will stop iterating. This is solved with itertools.zip_longest, which would output None in correspondence of the out-of-bound index: should you want to use it, you have to import the itertools module
If you want q=[1, 2, 3, 4, 45] and z=[1,4,4] in the first (and only) iteration of the for loop, you should return [[list1, list2]].
However, if you plan to only have one pair of lists returned, you can skip the for loop altogether (and keep the code you posted in the question):
q, z = testing_something()
print(q, z)
you can't iterate over single variable as your doing in your for loop,this is the easy way to q,z as your lists.
def testing_something():
list1 = [1,2,3,4,45]
list2 = [1,4,4]
return list1, list2
q,z=testing_something()
print q
print z
Related
Hello I have a few lists and im trying to create a new list of the highest values repsectively. for an example, these are the lists:
list1 = 5, 1, 4, 3
list2 = 3, 4, 2, 1
list3 = 10, 2, 5, 4
this is what I would like it to return:
[10, 4, 5, 4]
I thought that I could do a something like this:
largest = list(map(max(list1, list2, list3)))
but I get an error that map requires more than 1 argument.
I also thought I could write if, elif statements for greater than but it seems like it only does the first values and returns that list as the "greater value"
thanks for any help
This is the "zip splat" trick:
>>> lists = [list1, list2, list3]
>>> [max(col) for col in zip(*lists)]
[10, 4, 5, 4]
You could also use numpy arrays:
>>> import numpy as np
>>> np.array(lists).max(axis=0)
array([10, 4, 5, 4])
You have used map incorrectly. Replace that last line with this:
largest = list(map(max, zip(list1, list2, list3)))
In map, the first argument is the function to be applied, and the second argument is an iterable which will yield elements to apply the function on. The zip function lets you iterate over multiple iterables at once, returning tuples of corresponding elements. So that's how this code works!
Using map's iterableS argument has an implicit zip-like effects on the iterables.
map(max, *(list1, list2, list3))
I have an exercise for a class in python and i have stuck in question 4:
Create list1 with 200 random integers in space [1,50] and print how many times the number is 10.
Create list2 with 50 integers [1,2,3, ..., 50] and then with append() function join the lists together and display the size.
Delete the data with index number from 99 to 130 and print the list size after deleting items.
Find the maximum and minimum in the list.
My first thought on how to find MAX was to sort the list and get the last value but because 1 item in the list is a list I get this error TypeError: '<' not supported between instances of 'list' and 'int'.
Any ideas on what i have to do?
My code until this question is the one below:
import numpy as np
#Question1
j= 0;
list1 = list(range(200)) #decalre list1
for i in range(200):
list1[i] = np.random.randint(50) #create a list of length 200 with values 0 to 50.
if list1[i] == 10:
j = j+1
print("Number 10 exists ",j,"times in the list.")
#QUESTION2
list2 = list(range(1,51)) #Declare list2
list1.append(list2) #append list2 on list1
print(len(list1))
#QUESTION3
for i in range(99,130): # deletes the items with an index number from 99 to 130
list1.pop(i)
print(len(list1))
You need to flatten your list first before you can make any comparisons as you can't compare a list with an int. In order to do this you can create a recursive function and pass your list
def flatten(l):
return sum(([x] if not isinstance(x, list) else flatten(x) for x in l), [])
Be aware the the list in the above code is a protected name by Python and refers to a list data type. What this function does is compare each item in the lists and checks if it is a list type. If not it adds it to the list, if it is it calls the function again and goes to the next item. You can now run the following:
>>> list1 = [1, 2, 3, 4, [5, 6, 7, 8]]
>>> flatten(list1)
>>> [1, 2, 3, 4, 5, 6, 7, 8]
You can now run Python's built in max() and min() functions
>>> max(flatten(list1))
>>> 8
>>> min(flatten(list1))
>>> 1
Python provides a built-in function to solve this problem:
max([2, 5, 4, 9, 3, 7])
9
I would merge the lists, so appending the items of list2 to list1, so you just have only one axis, then you can use the built-in function
If you don't want to merge the list you can first get the maximum of the list inside the list. Then you can take the maximum of this maximum and the other part of your outer list.
Also you can change this line:
list1[i] = np.random.randint(50)
You can import random (it's a built-in module) instead and do it this way:
list1[i] = random.randint(1, 50)
but probably numpy is faster.
If you want to use numpy you nevertheless need to change the line to:
list1[i] = np.random.randint(1, 50)
You need to change your deleting loop in question 3, because if you delete item 99 then the item 100 is the new item 99, so you delete only each second element. You can fix that problem by going backwards from 130 to 99:
for i in range(130, 99):
I hope i could help you with this question.
Here is the code added in your code:
list2 = list1.pop(-1)
list3 = list1 + list2
print(max(list3))
print(min(list3))
Notice there are two lists in list1!
I was trying to execute a for loop like:
a = [1,2,3,4,5,6,7]
for i in range(0, len(a), 1):
if a[i] == 4:
a.remove(a[i])
I end up having an index error since the length of the list becomes shorter but the iterator i does not become aware.
So, my question is, how can something like that be coded? Can the range of i be updated in each iterations of the loop based on current array condition?
For the .pop() that you mention for example you can use a list comprehension to create a second list or even modify the original one in place. Like so:
alist = [1, 2, 3, 4, 1, 2, 3, 5, 5, 4, 2]
alist = [x for x in alist if x != 4]
print(alist)
#[1, 2, 3, 1, 2, 3, 5, 5, 2]
As user2393256 more generally puts it, you can generalize and define a function my_filter() which will return a boolean based on some check you implement in it. And then you can do:
def my_filter(a_value):
return True if a_value != 4 else False
alist = [x for x in alist if my_filter(x)]
I would go with the function solution if the check was too complicated to type in the list comprehension, so mainly for readability. The example above is therefore not the best since the check is very simple but i just wanted to show you how it would be done.
If you want to delete elements from your list while iterating over it you should use list comprehension.
a = [1,2,3,4,5,6,7]
a = [x for x in a if not check(x)]
You would need to write a "check" function that returns wether or not you want to keep the element in the list.
I don't know where you are going with that but this would do what I beleive you want :
i=0
a = [1,2,3,4,5,6,7]
while boolean_should_i_stop_the_loop :
if i>=len(a) :
boolean_should_i_stop_the_loop = False
#here goes what you want to do in the for loop
print i;
a.append(4)
i += 1
I have a spectra of wavelengths as a list and some number of other lists I use in a formula (using tmm.tmm_core). Is there something more efficient than iterating through the wavelength if I'm just basically doing the same thing for all wavelengths?
Example
def go(n, thk, theta):
#do stuff
return(something)
wv = [1, 2, 3, 4]
a_vec = [3, 7, 3, 9]
b_vec = [6, 5, 9, 3]
c_vec = [0, 1, 8, 9]
theta = 0
th = [10, 1, 10]
final = []
for i in range(len(wv)):
n = [a[i], b[i], c[i]]
answer = go(n, th, theta)
final.append(answer)
in reality there are maybe 5000-10000 rows. It just seems to lag a bit when I press go and I assume it's because of the iteration. Pretty new to optimizing so I haven't used any benchmarking tools or anything.
I think you're looking for the map function in Python!
>>> list1 = [1,2,3,4]
>>> list2 = [5,6,7,8]
>>> map(lambda x,y: x+y, list1, list2)
[6, 8, 10, 12]
it takes in a function (in the above case, an anonymous lambda function), one or more lists and returns another list. At each iteration within the function, both lists are iterated and the result is added to the new list. You don't need to limit yourself to the expressive power of a lambda statement; you can also use globally defined functions as in the case below:
>>> def go(a,b,c):
... return a+b+c
...
>>> map(go, list1,list2, range(9,13))
[15, 18, 21, 24]
You can put all of your lists within a custom list like C_list and use map to create a new list all_len contain the length of all lists then use a list comprehension to create the list final :
all_len=map(len,C_list)
final =[[go([a[i], b[i], c[i]], th, theta) for i in range(li)] for li in all_len]
Also if the length of a and b and c are equal you can use zip function to zip then and refuse of multiple indexing :
all_len=map(len,C_list)
z=zip(a,b,c)
final =[[go(z[i], th, theta) for i in range(li)] for li in all_len]
If you have to perform an operation on every item in the list, then you're gonna have to go through every item in the list. However, you could gain speed through the use of list comprehensions: List Comprehensions
I'm using python 2.7 I'm trying to figure out a way to change the names of my lists automatically.
Let me explain i have multiple lists
list1 = [1, 2, 3, 4, 5]
list2 = [4, 5, 9, 3]
list3 = [8, 4, 3, 2, 1]
I would like to call the lists in a loop to determine which lists contain or do not contain a particular number.
My first thought was
x = "list" + str(i) # (where i iterates in the loop)
print x
However, using the above code only gave me the string "list1"(when i=1).
What I want is to be able to call the list that is named list1 and use the .count() operator to determine whether or not the number exists if it doesn't i want to call the next list until I'm out of lists(there will eventually be up to 30 lists).
Thanks,
Ryan
You shouldn't approach it like this. Put your lists in a container to iterate over them instead:
In [5]: for l in (list1, list2, list3):
...: print l.count(2)
...:
1
0
1
What you could do in a real-life use case is create a list of lists and fill it dynamically.
Then to get the first list that contains a given number, you could do:
In [6]: lists = [list1, list2, list3]
In [7]: next(l for l in lists if 9 in l)
Out[7]: [4, 5, 9, 3]
put the list in dict:
list1 = [1,2.4]
list2 = [2,5,6]
dlist = {1:list1,2:list2}
for k in dlist:
print dlist[k]