Appending an element in nested list comprehension python - python

My (derailed) mind would like to do the following:
list1 = [1,2,3]
list2 = ['a','b','c']
list3 = [list([a for a in list2]).append(n) for n in list1]
to output this:
[['a', 'b', 'c', '1'], ['a', 'b', 'c', '2'], ['a', 'b', 'c', '3']]
only using single line list comprehensions (yes I'm in blinded by Haskell love).
Instead it outputs a list of 3 None type items which is understandable as I'm getting the output of append 3 times.
I think there's a key python idea I'm missing here on how I could make this work (or me being completely illogical), any help would be appreciated :)

No need to over-complicate things.
>>> list1 = [1,2,3]
>>> list2 = ['a','b','c']
>>> [list2 + [x] for x in list1]
[['a', 'b', 'c', 1], ['a', 'b', 'c', 2], ['a', 'b', 'c', 3]]

Related

concat two lists in a list of lists

Is it possible to concat two lists in a list of lists?
From:
listA = ['a', 'b', 'c']
listB = ['A', 'B', 'C']
listFull = listA + listB
To:
print(listFull)
[['a', 'A'],['b', 'B'],['c', 'C']]
List comprehension using zip()
listFull = [list(x) for x in zip(listA, listB)]
print(listFull)
You can also use map() without looping
listFull = list(map(list, zip(listA, listB)))
[['a', 'A'],['b', 'B'],['c', 'C']]
there are several ways to achieve this.
you either need atleast 1 for loop or a map/zip combination.
both possibilities here:
listA = ['a', 'b', 'c']
listB = ['A', 'B', 'C']
#1
listFull =[]
for i in range(len(listA)):
listFull.append([listA[i],listB[i]])
print(listFull)
# output [['a', 'A'], ['b', 'B'], ['c', 'C']]
#2
listfull2 = list(map(list,zip(listA,listB)))
print(listfull2)
# output [['a', 'A'], ['b', 'B'], ['c', 'C']]
"Concatenate" is what the + does, which puts one list after another. What you're describing is called a "zip" operation, and Python has exactly that function built-in.
zip returns an iterable, so if you want a list, you can call list on it.
print(list(zip(listA, listB)))
# Output: [('a', 'A'), ('b', 'B'), ('c', 'C')]

How to Check it is list or list of list in python

I have two lists below
list1 = ['a', 'b', 'c']
list2 = [['a', 'b', 'c'], ['e', 'f', 'g']]
Now I have to find
Is list1 is list of list
Expected result "False"
Is list2 is list of list
Expected result is "True"
How to achieve this
If you want to know if anything in the list is a list:
any(isinstance(a, list) for a in list1)
If you want to know if all the things in the list are lists:
all(isinstance(a, list) for a in list1)
This takes advantage of passing a generator expression to all().
list1 = ['a', 'b', 'c']
list2 = [['a', 'b', 'c'], ['e', 'f', 'g']]
print(type(list1[0]))
print(type(list2[0]))
Output:
<class 'str'>
<class 'list'>

How to merge two lists into a list of multiple lists?

Given two lists lst1 and lst2:
lst1 = ['a']
lst2 = [['b'],
['b', 'c'],
['b', 'c', 'd']]
I'd like to merge them into a list of multiple lists with a desired output like this:
desiredList = [['a', ['b']],
['a', ['b', 'c']],
['a', ['b', 'c', 'd']]]
Here is one of my attempts that comes close using lst1 + lst2 and list.append():
lst3 = []
for elem in lst2:
new1 = lst1
new2 = elem
theNew = new1 + new2
lst3.append(theNew)
print(lst3)
#Output:
#[['a', 'b'],
#['a', 'b', 'c'],
#['a', 'b', 'c', 'd']]
Expanding on this, I thought another variation with theNew = new1.append(new2)would do the trick. But no:
lst3 = []
for elem in lst2:
new1 = lst1
new2 = elem
#print(new1 + new2)
#theNew = new1 + new2
theNew = new1.append(new2)
lst3.append(theNew)
print(lst3)
# Output:
[None, None, None]
And you'll get the same result with extend.
I guess this should be really easy, but I'm at a loss.
Thank you for any suggestions!
You could achieve your desired output with itertools.zip_longest with a fillvalue:
>>> from itertools import zip_longest
>>> list(zip_longest(lst1, lst2, fillvalue=lst1[0]))
[('a', ['b']), ('a', ['b', 'c']), ('a', ['b', 'c', 'd'])]
Or if you need a list of lists:
>>> [list(item) for item in zip_longest(lst1, lst2, fillvalue=lst1[0])]
[['a', ['b']], ['a', ['b', 'c']], ['a', ['b', 'c', 'd']]]
Note this assumes that lst1 always contains a single element as in your example.
Or you can use use append, but you need to create new copy of the lst1:
lst3 = []
for elem in lst2:
theNew = lst1[:]
theNew.append(new2)
lst3.append(theNew)
print(lst3)
from itertools import product
list(product(lst1,lst2))
>>>[('a', ['b']), ('a', ['b', 'c']), ('a', ['b', 'c', 'd'])]
[lst1 + [new] for new in lst2]
>>>[['a', ['b']], ['a', ['b', 'c']], ['a', ['b', 'c', 'd']]]
This might help
desiredlist = list(map(lambda y:[lst1,y],lst2))

List comprehension with elements appearing twice

Suppose I have list
l = ['a', 'c', 'b']
and what I want is a list where those elements appear twice, one after the other, so
['a', 'a', 'c', 'c', 'b', 'b']
and I want to do this in the most pythonic way possible.
My half solution is doing something like
[[l[i], l[i]] for i in range(len(l))]
which yields
[['a', 'a'], ['c', 'c'], ['b', 'b']]
From here, I'd have to parse (walk) the list to remove the inner lists and obtain a single flat list.
Anyone has a better idea to do this in one go? Obviously things like l * 2 wouldn't help as it gives ['a', 'c', 'b', 'a', 'c', 'b'] and I want the same elements adjacent.
l_2 = [item for item in l for i in range(n)]
Link to origin: Stackoverflow: Repeating elements of a list n times
Using only list comprehension, you can do:
[i for j in my_list for i in [j]*2]
Output:
>>> my_list = ['a', 'c', 'b']
>>> [i for j in my_list for i in [j]*2]
['a', 'a', 'c', 'c', 'b', 'b']
You can zip the list against itself, then flatten it in a list comprehension.
>>> [i for j in zip(l,l) for i in j]
['a', 'a', 'c', 'c', 'b', 'b']
You can use zip function
l = ['a', 'c', 'b']
a = [i for j in zip(l,l) for i in j]
print(a)
Output
['a', 'a', 'c', 'c', 'b', 'b']
More general:
def ntimes(iterable, times=2):
for elt in iterable:
for _ in range(times):
yield elt
Here is a short solution without list comprehension, using the intuitive idea l*2:
sorted(l*2, key=l.index)
#['a', 'a', 'c', 'c', 'b', 'b']
If you like functional approaches, you can do this:
from itertools import chain, tee
l = ['a', 'c', 'b']
n = 2
list(chain.from_iterable(zip(*tee(l, n))))
While this might not perform as fast as the other answers, it can easily be used for arbitrary iterables (especially when they are infite or when you don't know when they end) by omitting list().
(Note that some of the other answers can also be adapted for arbitrary iterables by replacing their list comprehension by a generator expression.)

Keep strings that occur N times or more

I have a list that is
mylist = ['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd']
And I used Counter from collections on this list to get the result:
from collection import Counter
counts = Counter(mylist)
#Counter({'a': 3, 'c': 2, 'b': 2, 'd': 1})
Now I want to subset this so that I have all elements that occur some number of times, for example: 2 times or more - so that the output looks like this:
['a', 'b', 'c']
This seems like it should be a simple task - but I have not found anything that has helped me so far.
Can anyone suggest somewhere to look? I am also not attached to using Counter if I have taken the wrong approach. I should note I am new to python so I apologise if this is trivial.
[s for s, c in counts.iteritems() if c >= 2]
# => ['a', 'c', 'b']
Try this...
def get_duplicatesarrval(arrval):
dup_array = arrval[:]
for i in set(arrval):
dup_array.remove(i)
return list(set(dup_array))
mylist = ['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd']
print get_duplicatesarrval(mylist)
Result:
[a, b, c]
The usual way would be to use a list comprehension as #Adaman does.
In the special case of 2 or more, you can also subtract one Counter from another
>>> counts = Counter(mylist) - Counter(set(mylist))
>>> counts.keys()
['a', 'c', 'b']
from itertools import groupby
mylist = ['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd']
res = [i for i,j in groupby(mylist) if len(list(j))>=2]
print res
['a', 'b', 'c']
I think above mentioned answers are better, but I believe this is the simplest method to understand:
mylist = ['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd']
newlist=[]
newlist.append(mylist[0])
for i in mylist:
if i in newlist:
continue
else:
newlist.append(i)
print newlist
>>>['a', 'b', 'c', 'd']

Categories