How can i do it with list comprehension? [duplicate] - python

This question already has answers here:
if else in a list comprehension [duplicate]
(8 answers)
What does "list comprehension" and similar mean? How does it work and how can I use it?
(5 answers)
Closed 6 years ago.
I want to make a list comprehension with duplicated values at one loop cycle like this:
s=[]
for i in range(5):
s+=[i,i]
But this doesnt work.
[i, i for i in range(5)]

You can do it like this:
[i for i in range(5) for j in range(2)]
The output is:
[0, 0, 1, 1, 2, 2, 3, 3, 4, 4]
The i loop provides the values, and the j loop serves to repeat those values.

Here is one way with zip:
[i for p in zip(range(5), range(5)) for i in p]

There's no direct way to use a single level list comprehension to do exactly the same thing you're doing with your explicit loop. That's because each iteration of the loop in a comprehension must produce at most one value (it can produce zero if you have an if clause).
However, for this specific case, you can use division to produce the sequence of repeated values you want while iterating on a larger range:
s = [i//2 for i in range(10)]

I think this will do the trick.
[ i/2 for i in range(10)]
List comprehension will have as many elements as the iterator within the comprehension. In this case, the iterator is range(10)
Since, you need 10 elements. You will need to range over 10 and apply some computation( in this case i/2) to get the desired element.

You may try this:
s = [[i, i] for i in range(5)].
And if you want it to be flattened you can try this nested list comprehension.
s = [x for y in [[i, i] for i in range(5)] for x in y]

Related

Different way to create list within a list [duplicate]

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 1 year ago.
I have a question about how to create a list within a list. For example, we use
[[0] * n for _ in range(m)]
to create a matrix with dimension n*m. However, when I tried the similar thing to create a nested list.
l = [[(0, 1)]] * n
And then update the l[0], I find the l[1] would also get updated. However, the approach l = [[(0, 1)] for _ in range(n)] produces what I need.
Would you please help me understand this issue?
Thanks for your help.
Follow up:
In the dynamic programming, we use [-math.inf]*n to construct a list and then update the values. Why this approach works, but the above approach failed? Thanks.
The base list comprehension format
[0 for i in range(some_value)]
does create a list with some_value number of 0s. Using _ instead if i just discards it directly.
Now if you want a nested list, first question is, if outer list is rows or columns, however since most often it is matrix[row][column] i will go with it. So lets say you want 10 rows you need 10 items so
[row for i in range(number_rows)]
now what is your definition of a row
[0 for i in range(number_columns)]
if it is initialized with 0s.
Putting the two together, we get
columns, rows = 3,5
l = [[0 for i in range (columns)] for j in range(rows)]
EDIT:
Why [[[0] * n] * m] doesn't work:
When you multiply a mutable object, such as a list, it is not copied, but referenced, meaning, both list entries do point to the same variable in memory. The problem is referred to as deep copy vs shallow copy. It can be observed by calling id of an object.
l = [[1,2,3]]*3
Out[43]: [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
[id(i) for i in l]
Out[44]: [139708443372224, 139708443372224, 139708443372224]
As you can see, all items refer to the same variable, and hence, changing one changes all.

Ternary operator in enumeration loop [duplicate]

This question already has answers here:
list comprehension with multiple conditions (python)
(2 answers)
Closed 6 years ago.
In my code, I'm trying to loop through an enumeration object and selectively add some values from the enumeration to a new list using a list comprehension.
This works:
a = [1, 2, 3, 4, 5]
s = [i[1] for i in enumerate(a)]
Of course, that basically just copies list a over to s.
This doesn't work (a being the same list):
s = [i[1] if i[1] != 2 for i in enumerate(a)]
I would think that this would just copy every element of list a over to s besides the 2, but instead I get a syntax error. Anybody know what's going on here?
You misplaced the if part:
s = [i[1] for i in enumerate(a) if i[1] != 2]

Sort a lot of lists with small amount of code [duplicate]

This question already has answers here:
Understanding the map function
(6 answers)
Closed 6 years ago.
Is there a way to sort a lot of lists without having to write:
list.sort(list1)
list.sort(list2)
list.sort(list3)
...
for every single list?
It is very tedious when you have a lot of lists
Probably best to use a for-loop:
lists = [1, 2, -1], [2, 0, 6], [91, 3, 82]
for l in lists: l.sort()
list1, list2, list3 = lists
Now each list is sorted accordingly.
You could of course map it, but that's overkill since you'll also need to expand it into a list with list and dump away the resulting Nones produced as a side-effect:
_ = list(map(list.sort, lists))
you don't even Combine your lists to a named variable, so the code takes only 2 lines
l1 = [6,5,4,3,2,1]
l2 = [16,9,4,1]
#start of code
for my_l in [l1,l2]:
list.sort(my_l)
#stop of code
print l1
print l2

Duplicating list items variable number of times with list comprehension [duplicate]

This question already has answers here:
Double Iteration in List Comprehension [duplicate]
(11 answers)
Create duplicates in the list
(9 answers)
Closed 6 months ago.
I am basically trying to get my head around using a list comprehension with this basic bit of code. Im trying to duplicate a list item by the value of the list item:
y = [1, 2, 0, 1]
x = []
for i in y:
for j in range(i):
x.append(i)
# Desired output
>>> [1, 2, 2, 1]
x = [i for _ in range(i) for i in y]
# Wrong output
>>> [1, 2, 0, 1]
# Right output
x = [j for j in y for _ in range(j)]
>>> [1, 2, 2, 1]
I just cant seem to get my head around why I get the wrong output for the second example. Could someone explain what is wrong here. Thanks.
When you have multiple for loops inside a list comprehension, the loops are processed in the same order as they would be using "traditional" for loops. Your list comp that gives the correct output has the loops in the same order as your code at the start using .append with traditional for loops.
As Rahul mentions in the comments, in isolation,
x = [i for _ in range(i) for i in y]
would give a
NameError: name 'i' is not defined
It doesn't in this case because i was defined by the earlier code.
In contrast, look at what happens with a nested list comp:
y = [1, 2, 0, 1]
x = [[j for j in range(i)] for i in y]
print(x)
output
[[0], [0, 1], [], [0]]
Here, the outermost loop is in the outer comprehension and the inner loop is in the inner comprehension. So for each iteration of the for i in y we create a new list comp, and in that list comp we loop over range(i).
The right comprehension is:
x = [i for i in y for j in range(i)]
This give the result you want
item for item in list range(item) times
inspired by this thread
flattened = [val for sublist in list_of_lists for val in sublist]
x = [j for j in y for i in range(j)]

Pythonic Referenced For Loop [duplicate]

This question already has answers here:
Python Referenced For Loop
(3 answers)
Closed 8 years ago.
I have a for loop as follows:
a=[1,2,3,4,5]
for i in a:
i=6
What I would like is for every element of a to become 6.
Now I know that this for loop won't do it, because I am merely changing the what i refers to.
I instead could write:
a=[1,2,3,4,5]
for i in len(range(a)):
a[i]=6
But that doesn't seem very Pythonic. What are good ways of doing this sort of thing? Obviously, setting everything to 6 is contrived example and, in reality, I would be doing more complicated (and wonderful) things. Therefore, answers should be generalised.
The for-variable is always a simple value, not a reference; there is no way to know that it came from a list and thus write back to the list on changing.
The len(a) approach is the usual idiom, although you need range (or xrange) too:
for i in range(len(a)):
or, just as commonly, use the enumerate function to get indexes as well as values:
for i, v in enumerate(a):
a[i]= v+1
a list comprehension might be a good alternative, eg:
a= [6 for v in a]
This would probably be a good use for map() depending on what you're doing in real life. For example:
a = map(lambda x: 6, a)
You could use:
>>> a = [1, 2, 3, 4, 5]
>>> a = [6] * len(a)
>>> a
[6, 6, 6, 6, 6]

Categories