I need to replace the blank spaces or None values from this 2-d list
chess_board = [ [rook_3, knight_3, bishop_3, queen_2, king_2, bishop_4, knight_4, rook_4],
[pawn_9, pawn_10, pawn_11, pawn_12, pawn_13, pawn_14, pawn_15, pawn_16],
[],
[],
[],
[],
[pawn_1, pawn_2, pawn_3, pawn_4, pawn_5, pawn_6, pawn_7, pawn_8],
[rook_1, knight_1, bishop_1, queen_1, king_1, bishop_2, knight_2, rook_2]
]
Test for truthiness in a boolean context with a list comprehension:
[i for i in chess_board if i]
>>> x = [[1, 2], [], [3, 4]]
>>> [i for i in x if i]
[[1, 2], [3, 4]]
>>>
Related
Currently I am tidying up one of my projects by using the more pythonic way of dong things. Now I struggle extending a list by values from a dictionary that are lists.
my_dict = {'a': [1, 2, 3], 'b': [2, 3, 4], 'c': [4, 5, 6]}
criteria = ['a', 'c']
my_list = []
for c in criteria:
my_list.extend(my_dict[c])
Results in [1, 2, 3, 4, 5, 6] which is the sought for result, where as
my_list = []
my_list.extend(my_dict[c] for c in criteria)
Results in a nested list [[1, 2, 3], [4, 5, 6]]. I can't quite find a reason why this is happening
Your code does not work because it attempts to extend the list with the result of the generator comprehension, which is a list of lists:
>>> list(my_dict[c] for c in criteria)
[[1, 2, 3], [4, 5, 6]]
This is because my_dict[c] is itself a list.
A more Pythonic way is to use a list comprehension:
my_dict = {'a': [1, 2, 3], 'b': [2, 3, 4], 'c': [4, 5, 6]}
criteria = ['a', 'c']
my_list = [item for k in criteria for item in my_dict[k]]
>>> my_list
[1, 2, 3, 4, 5, 6]
This uses a nested loop to select the values from the dict by criteria and to flatten the lists that are those values.
I searched the net but couldn't find anything. I am trying to get all possible combinations including all subsets combinations of two lists (ideally n lists). All combinations should include at least one item from each list.
list_1 = [1,2,3]
list_2 = [5,6]
output = [
[1,5], [1,6], [2,5], [2,6], [3,5], [3,6],
[1,2,5], [1,2,6], [1,3,5], [1,3,6], [2,3,5], [2,3,6], [1,5,6], [2,5,6], [3,5,6],
[1,2,3,5], [1,2,3,6],
[1,2,3,5,6]
]
All I can get is pair combinations like [1,5], [1,6], .. by using
combs = list(itertools.combinations(itertools.chain(*ls_filter_columns), cnt))
What is the pythonic way of achieving this?
Here is one way:
from itertools import combinations, product
def non_empties(items):
"""returns nonempty subsets of list items"""
subsets = []
n = len(items)
for i in range(1,n+1):
subsets.extend(combinations(items,i))
return subsets
list_1 = [1,2,3]
list_2 = [5,6]
combs = [list(p) + list(q) for p,q in product(non_empties(list_1),non_empties(list_2))]
print(combs)
Output:
[[1, 5], [1, 6], [1, 5, 6], [2, 5], [2, 6], [2, 5, 6], [3, 5], [3, 6], [3, 5, 6], [1, 2, 5], [1, 2, 6], [1, 2, 5, 6], [1, 3, 5], [1, 3, 6], [1, 3, 5, 6], [2, 3, 5], [2, 3, 6], [2, 3, 5, 6], [1, 2, 3, 5], [1, 2, 3, 6], [1, 2, 3, 5, 6]]
Which has more elements then the output you gave, though I suspect that your intended output is in error. Note that my code might not correctly handle the case in which there is a non-empty intersection of the two lists. Then again, it might -- you didn't specify what the intended output should be in such a case.
Here is another way.
Even though it is not fancy, it cares n_lists easily.
def change_format(X):
output = []
for x in X:
output += list(x)
return output
import itertools
list_1 = [1,2,3]
list_2 = [5,6]
list_3 = [7,8]
lists = [list_1, list_2, list_3]
lengths = list(map(len, lists))
rs_list = itertools.product(*[list(range(1, l+1)) for l in lengths])
output = []
for rs in rs_list:
temp = []
for L, r in zip(lists, rs):
temp.append(list(itertools.combinations(L, r)))
output += list(itertools.product(*temp))
output = list(map(change_format, output))
I have managed to make it work for n-lists with less code, which was a challenge for me.
from itertools import chain, combinations, product
def get_subsets(list_of_lists):
"""
Get all possible combinations of subsets of given lists
:param list_of_lists: consists of any number of lists with any number of elements
:return: list
"""
ls = [chain(*map(lambda x: combinations(e, x), range(1, len(e)+1))) for e in list_of_lists if e]
ls_output = [[i for tpl in ele for i in tpl] for ele in product(*ls)]
return ls_output
list_1 = [1, 2, 3]
list_2 = [5, 6]
list_3 = [7, 8]
ls_filter_columns = [list_1, list_2, list_3]
print(get_subsets(ls_filter_columns))
Is there anyway to change this list comprehension to normal for loop representation.
result=[[]]
result = [x+[y] for x in result for y in sublist]
Edit:
Here is the full code, which i am trying to understand using loops.
result = [[]]
mainlist = [(1,2,3), (1,2,3)]
print(mainlist)
for sublist in mainlist:
result = [x+[y] for x in result for y in sublist]
print(result)
Output(result):
[[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
The output will be out.
x = [] # OP was assigning this constant expression to x.
out = []
for y in sublist:
out.append(x + [y])
This is tricky, because it is essentially not a list comprehension on its own but a for-loop combined with a list comprehension.
result = [[]]
mainlist = [(1,2,3), (1,2,3)]
for sublist in mainlist:
out = []
for x in result:
for y in sublist:
out.append(x+[y])
result = out
print(result)
In my mind this two pieces of code do the same thing:
l = [[1,2], [3,4],[3,2], [5,4], [4,4],[5,7]]
1)
In [4]: [list(g) for k,g in groupby(sorted(l,key=lambda x:x[1]),
key = lambda x:x[1]) if len(list(g)) == 2]
Out[4]: [[]]
2)
In [5]: groups = [list(g) for k,g in groupby(sorted(l,
key=lambda x:x[1]), key = lambda x:x[1])]
In [6]: [g for g in groups if len(g) == 2]
Out[6]: [[[1, 2], [3, 2]]]
But as you see first one gives an empty list while the second one gives what I need. Where am I mistaken?
The group is an iterator, you cannot consume it (e.g. by calling list on it) twice. For example:
>>> from operator import itemgetter
>>> from itertools import groupby
>>> l = [[1,2], [3,4],[3,2], [5,4], [4,4],[5,7]]
>>> for _, group in groupby(sorted(l, key=itemgetter(1)), key=itemgetter(1)):
... print('first', list(group))
... print('second', list(group))
...
first [[1, 2], [3, 2]]
second []
first [[3, 4], [5, 4], [4, 4]]
second []
first [[5, 7]]
second []
Instead, you need to call list once per group and filter on the results of that, e.g. by using map:
>>> [lst for lst in map(list, (group for _, group in groupby(sorted(l, key=itemgetter(1))), key=itemgetter(1))) if len(lst) == 2]
[[[1, 2], [3, 2]]]
I have a dictionary dict1['a'] = [ [1,2], [3,4] ] and need to generate a list out of it as l1 = [2, 4]. That is, a list out of the second element of each inner list. It can be a separate list or even the dictionary can be modified as dict1['a'] = [2,4].
Given a list:
>>> lst = [ [1,2], [3,4] ]
You can extract the second element of each sublist with a simple list comprehension:
>>> [x[1] for x in lst]
[2, 4]
If you want to do this for every value in a dictionary, you can iterate over the dictionary. I'm not sure exactly what you want your final data to look like, but something like this may help:
>>> dict1 = {}
>>> dict1['a'] = [ [1,2], [3,4] ]
>>> [(k, [x[1] for x in v]) for k, v in dict1.items()]
[('a', [2, 4])]
dict.items() returns (key, value) pairs from the dictionary, as a list. So this code will extract each key in your dictionary and pair it with a list generated as above.
Assuming that each value in the dictionary is a list of pairs, then this should do it for you:
[pair[1] for pairlist in dict1.values() for pair in pairlist]
As you can see:
dict1.values() gets you just the values in your dict,
for pairlist in dict1.values() gets you all the lists of pairs,
for pair in pairlist gets you all the pairs in each of those lists,
and pair[1] gets you the second value in each pair.
Try it out. The Python shell is your friend!...
>>> dict1 = {}
>>> dict1['a'] = [[1,2], [3,4]]
>>> dict1['b'] = [[5, 6], [42, 69], [220, 284]]
>>>
>>> dict1.values()
[[[1, 2], [3, 4]], [[5, 6], [42, 69], [220, 284]]]
>>>
>>> [pairlist for pairlist in dict1.values()]
[[[1, 2], [3, 4]], [[5, 6], [42, 69], [220, 284]]]
>>> # No real difference here, but we can refer to each list now.
>>>
>>> [pair for pairlist in dict1.values() for pair in pairlist]
[[1, 2], [3, 4], [5, 6], [42, 69], [220, 284]]
>>>
>>> # Finally...
>>> [pair[1] for pairlist in dict1.values() for pair in pairlist]
[2, 4, 6, 69, 284]
While I'm at it, I'll just say: ipython loves you!
a list out of the second element of
each inner list
that sounds like [sl[1] for sl in dict1['a']] -- so what's the QUESTION?!-)