Is there a way to add multiple items to a list in a list comprehension per iteration? For example:
y = ['a', 'b', 'c', 'd']
x = [1,2,3]
return [x, a for a in y]
output: [[1,2,3], 'a', [1,2,3], 'b', [1,2,3], 'c', [1,2,3], 'd']
sure there is, but not with a plain list comprehension:
EDIT: Inspired by another answer:
y = ['a', 'b', 'c', 'd']
x = [1,2,3]
return sum([[x, a] for a in y],[])
How it works: sum will add a sequence of anythings, so long as there is a __add__ member to do the work. BUT, it starts of with an initial total of 0. You can't add 0 to a list, but you can give sum() another starting value. Here we use an empty list.
If, instead of needing an actual list, you wanted just a generator, you can use itertools.chain.from_iterable, which just strings a bunch of iterators into one long iterator.
from itertools import *
return chain.from_iterable((x,a) for a in y)
or an even more itertools friendly:
return itertools.chain.from_iterable(itertools.izip(itertools.repeat(x),y))
There are other ways, too, of course: To start with, we can improve Adam Rosenfield's answer by eliminating an unneeded lambda expression:
return reduce(list.__add__,([x, a] for a in y))
since list already has a member that does exactly what we need. We could achieve the same using map and side effects in list.extend:
l = []
map(l.extend,[[x, a] for a in y])
return l
Finally, lets go for a pure list comprehension that is as inelegant as possible:
return [ y[i/2] if i%2 else x for i in range(len(y)*2)]
Here's one way:
y = ['a', 'b', 'c', 'd']
x = [1,2,3]
return reduce(lambda a,b:a+b, [[x,a] for a in y])
x = [1,2,3]
y = ['a', 'b', 'c', 'd']
z = []
[z.extend([x, a]) for a in y]
(The correct value will be in z)
Related
a='sadfaad'
b=[]
b.append(x for x in a)
print(b)
It returns
[<generator object <genexpr> at 0x000002042A1DA5F0>]
What to know why it happens so? and how can we use list comprehension for it?
To get the actual result of the comprehension, you need to exhaust the generator by converting to list:
a='sadfaad'
b=[]
b.append([x for x in a])
print(b)
output: [['s', 'a', 'd', 'f', 'a', 'a', 'd']]
If you want to add the elements, use extend:
a='sadfaad'
b=[]
b.extend([x for x in a])
print(b)
output: ['s', 'a', 'd', 'f', 'a', 'a', 'd']
But, unless this is just a toy example, the best remains to convert without loop:
b = list(a)
print(b)
output: ['s', 'a', 'd', 'f', 'a', 'a', 'd']
You can also do a simple list comprehension like this:
a='sadfaad'
b = [x for x in a]
And that will return a list of characters in a
(x for x in a) # This will produce a generator that will yield x when called. Note '()' syntax
[x for x in a] # This will produce a list. Note the '[]' syntax
In fact, [x for x in a] can be thought of as a generator expression wrapped in a list constructor.
[x for x in a] is really the same as list(x for x in a)
This question already has answers here:
Duplicate each member in a list [duplicate]
(12 answers)
Closed 5 years ago.
I'd like to make the python's list to ['a','a','b',b','c','c'] from ['a','b','c'].
Anyboday know to do this?
Thank you !
For something that more or less says “I want to repeat each element twice”, there’s the nested list comprehension with range:
>>> l = ['a', 'b', 'c']
>>> [x for x in l for _ in range(2)]
['a', 'a', 'b', 'b', 'c', 'c']
You can make it a tiny bit shorter with a list multiplication if you find that more readable and won’t need to extend 2 to a large number and convert the list comprehension to a generator expression:
>>> l = ['a', 'b', 'c']
>>> [y for x in l for y in [x, x]]
If you’re a fan of Haskell, where l >>= replicate 2 would work, you can imitate that:
import itertools
from functools import partial
from operator import mul
def flat_map(iterable, f):
return itertools.chain.from_iterable(map(f, iterable))
l = ['a', 'b', 'c']
flat_map(l, partial(mul, 2))
You could always create a new list:
for x in oldList:
newList.append(x)
newList.append(x)
Note that this will create a new list rather than modifying the old one!
source = ['a','b','c']
result = [el for el in source for _ in (1, 2)]
print(result)
gives you
['a', 'a', 'b', 'b', 'c', 'c']
I am looking for an elegant way to slice a list l in python, given a list of ids l_ids.
For example, instead of writing
new_list = [l[i] for i in l_ids]
Write something like (Pseudo code):
new_list = l[*l_ids]
Is there a similar way to slice lists?
I have the feeling that someone have asked that already, but I couldn't find any reference for it.
Edit: It is OK to assume that all the list items are of the same type?
You can use operator.itemgetter(*items) like this:
from operator import itemgetter
getter = itemgetter(*lst_ids)
new_list = list(getter(lst))
Also, note that I renamed l variable to lst because it is less ambiguous and should be avoided.
You can implicitly cast the tuple to a list using Python 3 unpacking, as #JonClements commented:
*new_list, = getter(lst)
Finally, since Python 3.5, you can also use extended unpacking:
new_list = [*getter(lst)]
You could use itemgetter
from operator import itemgetter
l = ['a', 'b', 'c', 'd', 'e']
l_ids = [1, 2, 3]
list(itemgetter(*l_ids)(l))
['b', 'c', 'd']
I don't think importing anything is particularly elegant, or pythonic.
List comprehensions work, and I can't see a reason not to use them (or no good reason to import something to do the same thing):
>>> x = [3,5,7,0,1,4,2,6]
>>> y = ['a','b','c','d','e','f','g','h']
>>> nList = [y[i] for i in x]
>>> nList
['d', 'f', 'h', 'a', 'b', 'e', 'c', 'g']
The list comprehension is doing the following:
indexes = [3,5,7,0,1,4,2,6]
data = ['a','b','c','d','e','f','g','h']
nList = []
for index in indexes:
nList += [data[index]]
The comprehension looks pretty pythonic and elegant to me.
I would go with itemgetter but you could also map list.__getitem__:
l = ['a', 'b', 'c', 'd', 'e']
l_ids = [1, 2, 3]
new = list(map(l.__getitem__, l_ids))
If all the list elements are of the same type, it is possible to use numpy:
from numpy import *
new_list = array(l)[l_ids]
I have two lists:
input_list = ['a','b']
existing_list = ['q','w','r']
I want to create a new list that will be equal to input_list if it's not empty else it should be equal to existing_list.
The easiest way to do this is to use the plain if-else:
if input_list:
list_to_use = input_list
else:
list_to_use = existing_list
Is it possible to do this in a list comprehension or in any other manner that is more concise?
list_to_use = [x if input_list else y for y in existing_list for x in input_list]
The closest I could get is with this one that produces ['a', 'b', 'a', 'b', 'a', 'b'], a wrong result.
You don't need a list comprehension. That's exactly what or operation does:
>>> input_list or existing_list
['a', 'b']
>>> input_list = []
>>>
>>> input_list or existing_list
['q', 'w', 'r']
Other than or, that suggested by Kasramvd (which should be the way to do this), you can also use ternary operator.
list_to_use = input_list if input_list else existing_list
I want to make a loop for items in list that are not present in other_list, in one line. Something like this:
>>> list = ['a', 'b', 'c', 'd']
>>> other_list = ['a', 'd']
>>> for item in list not in other_list:
... print item
...
b
c
How is this possible?
for item in (i for i in my_list if i not in other_list):
print item
Its a bit more verbose, but its just as efficient, as it only renders each next element on the following loop.
Using set (which might do more than what you actually want to do) :
for item in set(list)-set(other_list):
print item
A third option: for i in filter(lambda x: x not in b, a): print(i)
list comprehension is your friend
>>> list = ['a', 'b', 'c', 'd']
>>> other_list = ['a', 'd']
>>> [x for x in list if x not in other_list]
['b', 'c']
also dont name things "list"