I have n lists as below:
List_1 = ['x1', 'y1', 'z1']
List_2 = ['x2', 'y2', 'z2']
List_3 = ['x3', 'y3', 'z3']
...
List_n = ['xn', 'yn', 'zn']
list_dict = {List_1: 'yes', List_2: 'yes', List_3: 'no', ..., List_n: 'yes'}
I want to make one larger list comprising of subset of smaller n lists and criteria to append members of a smaller list is defined in this dictionary 'list_dict', i.e. append members of List_1, List_2, List_n BUT NOT List_3
Final_List = ['x1', 'y1', 'z1', 'x2', 'y2', 'z2', ...., 'xn', 'yn', 'zn']
Also, it is preferable to use list comprehension OR lambda function to generate Final_List but not a must.
NOTE: 'list_dict' i.e. the criteria to append any smaller list does not have to be a dictionary if alternative options are available. NOW I cant define 'list_dict' using keys are variable names defined outside of 'list_dict', so maybe replacing variable name with equivalent strings is one option to define the dictionary such as below:
list_dict = {'List_1': 'yes', 'List_2': 'yes', 'List_3': 'no', ..., 'List_n': 'yes'}
BUT THEN we need a way to dynamically access strings as variable name using globals() method in namespace.
CodePudding user response:
The simplest thing is to keep a list of your lists, and do something like:
big_list = [['x1', 'y1', 'z1'], ['x2', 'y2', 'z2'], ['x3', 'y3', 'z3'], ['x4', 'y4', 'z4']]
list_dict = {1:True, 2:True, 3:False, 4:True}
Then you can easily build your final list:
final_list = [item for i, sub_list in enumerate(big_list, start=1) if list_dict[i] for item in sub_list]
final_list #['x1', 'y1', 'z1', 'x2', 'y2', 'z2', 'x4', 'y4', 'z4']
CodePudding user response:
Here's a way to do what your question asks without needing a dict, and hence avoiding the issue of hashing lists as "keys" in a dictionary:
List_1 = ['x1', 'y1', 'z1']
List_2 = ['x2', 'y2', 'z2']
List_3 = ['x3', 'y3', 'z3']
List_n = ['xn', 'yn', 'zn']
#list_dict = {List_1: 'yes', List_2: 'yes', List_3: 'no', List_n: 'yes'}
list_mask = [(List_1, 'yes'), (List_2, 'yes'), (List_3, 'no'), (List_n, 'yes')]
from functools import reduce
from operator import add
Final_List = reduce(add, (lst for lst, yesNo in list_mask if yesNo == 'yes'))
print(Final_List)
Output:
['x1', 'y1', 'z1', 'x2', 'y2', 'z2', 'xn', 'yn', 'zn']
Explanation:
- replace
list_dict
withlist_mask
, a list of pairs (I have used tuples, but lists would be fine as well) each containing a list reference and ayes/no
string - use a generator comprehension to create an iterable of the lists marked
yes
- use the
reduce
function fromfunctools
together withadd
fromoperator
to concatenate all these lists.
Note: If there's a possibility of duplicate members across different input lists, and we want the output list to have no duplicates, we can do this:
from functools import reduce
from operator import add
list_maybe_nonunique = reduce(add, (lst for lst, yesNo in list_mask if yesNo == 'yes'))
found = set()
Final_List = []
for item in list_maybe_nonunique:
if item not in found:
found.add(item)
Final_List.append(item)
print(Final_List)