How to loop over a list of lists - python

Recently I have come up with using a for loop to reform a list.
First, I did this:
list1 = [[1],[2],[3]]
list2 = []
for x in list1:
list2.append(x)
print(list2)
And the output was:
[[1], [2], [3]]
Then, I tried:
list2 = []
for x in list1:
list2.append(x[0])
And the output was:
[1, 2, 3]
Could someone please explain to me what x[0] does in this for loop? I thought this index would mean only taking the first element in a list.

x[0] returns the item at index 0 of the list x, so by appending to a new list with x[0] in your for loop, you are appending the value within the sub-list rather than the sub-list itself, thereby achieving the effect you want, flattening the list.

Could you please tell what does "x[0]" do in this for loop; I thought this index would mean only taking the first element in a list.
list1 = [[1],[2],[3]] is not simply a list but a list of lists. Every element of list1 is a list – albeit with only one sub-element. So you are effectively iterating over every list within your list list1, picking the first element at position 0 (which is all there is) and appending it to your new list list2.

When you go
for x in list1:
and print out x you'll get:
>[1]
>[2]
>[3]
Because each element in list1 are still lists! The lists only have one element but they're still stored within a list. When you use x[0] you're telling Python you want to access the first element of each list, which is the number you want.
Also another thing you could do which would be faster than a for loop is to use list comprehension:
list2 = [x[0] for x in list1]

list1 = [[1], [2], [3]]
for x in list1:
list2.append(x[0])
Okay lets just look at what we are doing here:
for x in list1:
Well x in this loop will represent [1], [2], [3] which are list containing a certain number in the 0 position.
A little more perspective lets look at it like this:
list1[0][0] = 1
list1[1][0] = 2
list1[2][0] = 3

You are iterating list containing list.
e.g :
a = [[1], [2], [3]]
a[0] will contain list [1] #i.e it is containing list
a[1] will contain list [2]
a[2] will contain list [3]
If you are want to access contents from list of list, you have to pass 2 indexes.
e.g :
a[0][0] will contain 1 #i.e it is containing element
a[1][0] will contain 2
a[2][0] will contain 3
You also can try extend keyword to achieve the same. The extend() method takes a single argument (a list) and adds it to the end.
list1 = [[1],[2],[3]]
list2 = []
for x in list1:
list2.extend(x)
print(list2)

Related

Assign elements of one list of lists to elements of another list of lists while keeping a sum constraint

I have two lists of lists and an empty list:
list_a = [[1], [6], [2]]
list_b = [[2], [8], [3]]
list_c = []
By extending the lists in list_b, I want to assign the values in the lists of list_a to the values in the lists of list_b in such a way that, in the end, the sum in each of the lists in list_b is smaller or equal than 8. If a value contained in a list of list_a cannot be assigned to list_b that way, it shall be appended to list_c. Each list in list_a can only be assigned to one list in list_b.
A possible result would be:
list_b = [[2, 1, 2], [8], [3]]
list_c = [[6]]
How can I do this in Python? I know that there are many possible results. I would be fine with a solution that gives one possible result. Please consider that the solution should also run for problems, in which the lists in list_a and list_b contain more than one value (so you might have to sum them up with sum(list_x)).
I tried to solve it with a nested loop and two if statements inside, but I could not get even close to an acceptable result.
Something like this?
for item in list_b:
a_index = 0
stuff = True
running = item[0]
while stuff:
cand = sum(list_a[a_index])
if cand + running <= 8:
item.append(list_a.pop(a_index))
running += cand
else:
a_index += 1
stuff = a_index < len(list_a)
for remainder in list_a:
list_c.append(list_a.pop(0))

python: create a new 1D list with values from 2 different lists: [duplicate]

This question already has answers here:
How do I concatenate two lists in Python?
(31 answers)
Closed 4 years ago.
Below is a simple example. What I want is to create a new list that contain the values [0,1,2,3,4] by merging list1 and list 2 together. But the code below doesn't work and I am not really sure how I should solve it.
list1 = [3]
list2 = [i for i in range(3)]
newlist = list1.append(list2)
list.append(b) doesn't return a new list containing the elements of list and b, but it will extend list by one element (the element b) and save the result in list itself.
To concatenate two lists, simply use the + operator. Your code would look like this:
list1 = [3]
list2 = [i for i in range(3)]
newlist = list1 + list2
#MathiasRa, your code will not work as append()
method doesn't return any list.
Previous answers are appreciated. So can directly get your merged list [0, 1, 2, 3] using the below line.
list1 = [3]
list2 = [i for i in range(3)]
newlist = sorted(list1 + list2)
print (newlist) # [0, 1, 2, 3]
» If you don't want updated list as return value
Use extend() method in place of append() as follows:
Note: In this case, you won't get anything returned like append(). The statement will update the calling list (list1) by appending all items of passing list (list2).
list1 = [3]
list2 = [i for i in range(3)]
list1.extend(list2)
print(list1) # [3, 0, 1, 2]
print(sorted(list1)) # [0, 1, 2, 3]

How to unpack list of lists with unknown number of elements into unique variables? [duplicate]

This question already has answers here:
How do I create variable variables?
(17 answers)
Closed 5 years ago.
I recently created a program that will give me a list of lists:
myList = [[1,2],[3,4],[5,6]]
However, I do not know how many lists this list will contain, but I do want to unpack it into unique variables that I can manipulate later (not a dictionary):
list1 = [1,2]
list2 = [3,4]
list3 = [5,6]
I have been trying to figure this out for a long time, but I can't. I would really appreciate some help.
You actually don't need to unpack them at all: The individual lists can be referenced as unique variables as they are now!
Instead of trying to reference the variables as list1 with new names, use their existing names:
myList = [[1,2],[3,4],[5,6]]
print (myList[0]) # Prints out the list [1,2]
print (myList[1]) #Prints out the list [3,4]
print (myList[2]) #Prints out the list [5,6]
There are advantages to this format, take for example this made up list:
myListOfUnexpectedSize = [[1,3],[5,7],...more lists...,[15,17]]
print(len(myListOfUnexpectedSize)) #Prints out the number of lists you have
for lis in myListOfUnexpectedSize: #This loop will print out all the lists one by one
print(lis)
print(myListOfUnexpectedSize[-1]) #Prints out the last list in the big list
So by using the size of the larger list, you can figure out how many lists you have inside and work with them.
What you may want is a collection, such as lists to hold each list, and then you can reference it by index. Alternatively, you could consider a dictionary and a bit of list comprehension as follows if you really want to reference it by a specific name
listDict = {"list" + str(key+1) : value for (key, value) in enumerate(myList)}
If you may have more than three sublists, you can try this:
myList = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
list1, list2, list3, *rest = myList
print(list1)
print(list2)
print(list3)
the rest will hold the remaining sublists, and the list1, list2, list3 are the ones you want.

Dynamic self-referencing conditional in list comprehension

Goal: Create a conditional statement in a list comprehension that (1) dynamically tests -- i.e., upon each iteration -- if the element is not in the list being comprehended given (2) the list is itself updated on each iteration.
Background code:
arr = [2, 2, 4]
l = list()
Desired output:
l = [2, 4]
Desired behavior via for loop:
for element in arr:
if element not in l:
l.append(element)
Incorrect list comprehension not generating desired behavior:
l = [element for element in arr if element not in l]
Question restated: How do I fix the list comprehension so that it generates the desired behavior, i.e., the desired output stated above?
If you absolutely must use a list comprehesion, you can just recast your for loop into one. The downside is that you will end up with a list of None elements, since that is what list.append returns:
>>> arr = [2, 2, 4]
>>> l = list()
>>> _ = [l.append(element) for element in arr if element not in l]
>>> print(l)
[2, 4]
>>> print(_)
[None, None]
If you are tied to comprehensions, but not necessarily to list comprehensions, you can use the generator comprehension suggested by #tdelaney. This will not create any unwanted byproducts and will do exactly what you want.
>>> arr = [2, 2, 4]
>>> l = list()
>>> l.extend(element for element in arr if element not in l)
A better way than either would probably be to put the original list into a set and then back into a list. The advantage of using a set to extending a list is that sets are much faster at adding elements after checking for prior containment. A list has to do a linear search and reallocate every time you add an element.
>>> l = list(set(arr))
if you want to remove duplicates why not use set(the list containing duplicates) or list(dict.fromkeys(the list containing duplicates)?
but to answer your Question:
i think the whole thing is just wrong, l (your list) doesn't get updated with each iteration since it's inside the list comprehension

Removing elements from a List in Python

I'm using python 3.4 and just learning the basics, so please bear with me..
listA = [1,2]
for a in listA:
listA.remove(a)
print(listA)
What is suppose is I get an empty list, but what I get is a list with value '2'. I debugged the code with large no. of values in list and when the list is having a single element the for loop exit.
Why is the last element not removed from the list..?
You should not change a list while iterating over it. The indices of the list change as you remove items, so that some items are never evaluated. Use a list comprehension instead, which creates a new list:
[a for a in list if ...]
In other words, try something like this:
>>> A = [1, 2, 3, 4]
>>> A = [a for a in A if a < 4] # creates new list and evaluates each element of old
>>> A
[1, 2, 3]
When you use a for-loop, an internal counter is used. If you shift the remaining elements to the left while iterating over the list, the left-most element in the remaining list will be not be evaluated. See the note for the for statement.
That happens because the length of the for is evaluated only at the beginning and you modify the list while looping on it:
>>> l = [1,2,3]
>>> l
[1, 2, 3]
>>> for a in l:
print(a)
print(l)
l.remove(a)
print(a)
print(l)
print("---")
1
[1, 2, 3]
1
[2, 3]
---
3
[2, 3]
3
[2]
---
>>>
See? The value of the implicit variable used to index the list and loop over it increases and skip the second element.
If you want to empty a list, do a clear:
>>> l.clear()
>>> l
[]
Or use a different way of looping over the list, if you need to modify it while looping over it.
As mentioned by #Justin in comments, do not alter the list while iterating on it. As you keep on removing the elements from the list, the size of the list shrinks, which will change the indices of the element.
If you need to remove elements from the list one-by-one, iterate over a copy of the list leaving the original list intact, while modifying the duplicated list in the process.
>>> listA = [1,2,3,4]
>>> listB = [1,2,3,4]
>>> for each in listA:
... print each
... listB.remove(each)
1
2
3
4
>>> listB
[]

Categories

Resources