How to create a list from lists? - python

fp.readline()
for line in fp:
line_lst = line.strip().split(',')
Suppose I get a bunch of lists after running the code above:
['a','b','c']['1','2','3']['A','B','C']
How could I get another lists
['a','1','A']['b','2','B']['c','3','C']
from the lists instead of directly creating it?

Assuming all lists have same number of elements
my_lists = [my_list_1, my_list2, ...]
for i in xrange(len(my_lists[0])):
print [l[i] for l in my_lists]
An example...
>>> my_lists = [['a','b','c'],['1','2','3'],['A','B','C']]
>>> for i in xrange(len(my_lists[0])):
... print [l[i] for l in my_lists]
...
['a', '1', 'A']
['b', '2', 'B']
['c', '3', 'C']

You could use
all_list = [['a','b','c'],['1','2','3'],['A','B','C']]
result = [x[0] for x in all_list]
print(result)
This is called list comprehension in Python.
For your need, you should use zip function here, the link is give by #Arc676.
all_list = [['a','b','c'],['1','2','3'],['A','B','C']]
# result = list(zip(all_list[0], all_list[1], all_list[2]))
# if you have more list in all_list, you could use this
result = list(zip(*all_list))
print(result)

You could try something like below.
var aggregateList = line_lst.map(function (value) { return value[0]; });
EDIT: Oops, thought I was in the javascript section, for python:
aggregateList = map(lambda value: value[0], line_lst)

This should do it... but it's really just getting the first item from each list, so I'm not sure if it's exactly what you want
new_list = []
for sub_list in line_lst:
new_list.append(sub_list[0])
you could also do this (which I like better)
new_list = [sub_list[0] for sub_list in line_lst]

Just:
zip(['a','b','c'], ['1','2','3'], ['A','B','C'])
Which gives:
[('a', '1', 'A'), ('b', '2', 'B'), ('c', '3', 'C')]

Related

how to add a item in a list of list using python

Is there any way to add a item to a list of list using python.
As an example there is a list as below:
test_list = [['abc','2'],['cds','333'],['efg']]
I want to add a item '444' for the position test_list[2][1].
At last list should be:
test_list = [['abc','2'],['cds','333'],['efg','444']]
Yes that is definitely something you can do.
You simply access the list object that you want to add another item to by its index, and then call .append() on that list object with the new value.
test_list = [['abc','2'], ['cds','333'], ['efg']]
test_list[2].append('444')
# test_list is now: [['abc','2'], ['cds','333'], ['efg', '444']]
test_list = [['abc','2'],['cds','333'],['efg']]
test_list[2].insert(1,"444")
print(test_list)
Try using append, append does your job:
>>> test_list = [['abc','2'],['cds','333'],['efg']]
>>> test_list[2].append('444')
>>> test_list
[['abc', '2'], ['cds', '333'], ['efg', '444']]
>>>
Or use +=, that adds stuff together, but two lists, so do:
>>> test_list = [['abc','2'],['cds','333'],['efg']]
>>> test_list[2] += ['444']
>>> test_list
[['abc', '2'], ['cds', '333'], ['efg', '444']]
>>>
append is a builtin python list method, here is the documentation for it, and for +=, that is a builtin addition operator, see the documentation for it.
Above Three are absolutely correct. But I want to add One thing If you want to add an element in a list of list and you don't know the ending index you can do something like,
>>> test_list = [['abc','2'],['cds','333'],['efg']]
>>> test_list[-1].append('444')
>>> test_list
[['abc', '2'], ['cds', '333'], ['efg', '444']]
you can also use cutting to do this:
test_list = [['abc', '2'], ['cds', '333'], ['efg']]
test_list[2][1:] = ['444']
print(test_list)
[['abc', '2'], ['cds', '333'], ['efg', '444']]

Flatten lists of variable depths in Python

I have a list of n lists. Each internal list contains a combination of (a) strings, (b) the empty list, or (c) a list containing one string. I would like to transform the inside lists so they only contain the strings.
I have a list like this for example:
[[[],["a"],"a"],[["ab"],[],"abc"]]
and I would like it to be like this:
[["","a","a"],["ab","","abc"]]
I know I could probably go through with a loop but I am looking for a more elegant solution, preferably with a list comprehension.
List comprehension:
>>> original = [[[],["a"],"a"],[["ab"],[],"abc"]]
>>> result = [['' if not item else ''.join(item) for item in sublist] for sublist in original]
>>> result
[['', 'a', 'a'], ['ab', '', 'abc']]
As every element of the list that you'd like to flatten is iterable, instead of checking of being instance of some class (list, string) you can actually make use of duck-typing:
>> my_list = [[[],["a"],"a"],[["ab"],[],"abc"]]
>> [list(map(lambda x: ''.join(x), elem)) for elem in my_list]
Or more readable version:
result = []
for elem in my_list:
flatten = map(lambda x: ''.join(x), elem)
result.append(list(flatten))
Result:
[['', 'a', 'a'], ['ab', '', 'abc']]
It's quite pythonic to not to check what something is but rather leverage transformation mechanics to adaptive abilities of each of the structure.
Via list comprehension:
lst = [[[],["a"],"a"],[["ab"],[],"abc"]]
result = [ ['' if not v else (v[0] if isinstance(v, list) else v) for v in sub_l]
for sub_l in lst ]
print(result)
The output:
[['', 'a', 'a'], ['ab', '', 'abc']]
original_list = [[[],["a"],"a"],[["ab"],[],"abc"]]
flatten = lambda x: "" if x == [] else x[0] if isinstance(x, list) else x
flattened_list = [[flatten(i) for i in j] for j in original_list]

Python iterate over array of arrays special way

I have this array of arrays:
[[[1111, 2222, 3333], [4444, 5555, 6666]], [[7777]], [[8888, 9999]], [[0000]], [[1122, 2233]]]
I need to get all the possible combinations IN ORDER of the elements of the list.
Expected output for this example:
[1111,2222,3333,7777,8888,9999,0000,1122,2233]
[4444, 5555, 6666,7777,8888,9999,0000,1122,2233]
As you may see in this example the first array of the array is the only one who has two options.
I've tried with something like:
for i in array_input:
for j in i:
print ', '.join([str(x) for x in j]),
but that is not getting me the expected output because is firstly iterating through the two array[0] options instead of picking one of them and filling the rest and then picking the other one and filling it.
So I want some loop that gets array[0][0],array[1][0],array[2][0]... instead of: array[0][0],array[0][1],array[1][0]...
thank you
Your elements are integers, so 0000 will be shown as 0:
import itertools as it
lst = [[[1111, 2222, 3333], [4444, 5555, 6666]], [[7777]], [[8888, 9999]], [[0000]], [[1122, 2233]]]
out = [list(it.chain.from_iterable(x)) for x in it.product(*lst)]
First itertools.product generates a product of all arguments. Then you need itertools.chain.from_iterable to flatten the list of lists.
You could use itertools.combinations, lets simplify your example to the list `l = ['a', 'b', 'c', 'd'] then you can generate all combinations of length r with:(here i.e. r = 3)
import itertools as it
l = ['a', 'b', 'c', 'd']
for e in it.combinations(l, 3):
print e
=> ('a', 'b', 'c')
('a', 'b', 'd')
('a', 'c', 'd')
('b', 'c', 'd')
if you want to get all combinations just loop your r over the length of l
to overcome the problem with the two arrays you could maybe flatten your list i.e. with something like
new_list = [item for sublist in l for item in sublist]
full example:
import itertools as it
l = [[[1111, 2222, 3333], [4444, 5555, 6666]], [[7777]], [[8888, 9999]], [[0000]], [[1122, 2233]]]
l = [item for sublist in l for item in sublist]
for n in range(1, len(l)):
for e in it.combinations(l, n):
print e
You can just do the following ...
import operator
reduce(operator.__add__, zip(*array_input)[0])
The zip(*array_input) basically unzips the array to ...
[([1111, 2222, 3333], [7777], [8888, 9999], [0], [1122, 2233])]
zip(*array_input)[0] simply remove one level of nesting ...
Finally the reduce operator adds the lists to a single list. You could also have done
reduce(lambda m, n: m+n, zip(*array_input)[0]) but I don't like using lambda functions here ...
list1 = [[[1111, 2222, 3333], [4444, 5555, 6666]], [[7777]], [[8888, 9999]], [[0000]], [[1122, 2233]]]
a = []
for i in list1:
for j in i:
for k in j:
a.append(k)
print(a)

Grouping two lists of lists in Python based on value

I have two lists in Python.
list1 = ['a','a','b','a','c','b','c','a','d','a','b']
list2 = ['1','2','21','12','1','32','11','12','21','3','31']
I have to group the similar elements in list1. The corresponding elements in list2 should also get grouped based on this. Output should be this:
list1 = [['a','a','a','a','a'],['b','b','b'],['c','c'],['d']]
list2 = [['1','2','12','12','3'],['21','32','31'],['1','11'],['21']]
What is the best way to do this?
If you do not care about the order of elements in the first list, you may use defaultdict:
In [7]: from collections import defaultdict
In [8]: from itertools import izip
In [9]: res = defaultdict(list)
In [10]: for k, v in izip(list1, list2):
....: res[k].append(v)
....:
In [11]: print(res)
defaultdict(<type 'list'>, {'a': ['1', '2', '12', '12', '3'], 'c': ['1', '11'], 'b': ['21', '32', '31'], 'd': ['21']})
In [12]: res.items()
Out[12]:
[('a', ['1', '2', '12', '12', '3']),
('c', ['1', '11']),
('b', ['21', '32', '31']),
('d', ['21'])]
This code worked for me:
groups = list(set(list1))
list1_tmp, list2_tmp = [], []
for char in groups:
list1_tmp.append([])
list2_tmp.append([])
for i in range(len(list1)):
list1_tmp[groups.index(list1[i])].append(list1[i])
list2_tmp[groups.index(list1[i])].append(list2[i])
list1 = list1_tmp
list2 = list2_tmp
The output should be valid as well for any other similar input.
This code should do it:
final_list1 = []
final_list2 = []
for distinct in sorted(list(set(list1))):
index = 0
distinct_list1 = []
distinct_list2 = []
for element in list1:
if element == distinct:
distinct_list1.append(element)
distinct_list2.append(list2[index])
index += 1
final_list1.append(distinct_list1)
final_list2.append(distinct_list2)
list1 = final_list1
list2 = final_list2
This will give you exactly the output you asked for. If you don't really care about the output, there are probably better ways as #soon proposed.
Here's a (kind of ugly) implementation that would do the trick:
list1 = ['a','a','b','a','c','b','c','a','d','a','b']
list2 = ['1','2','21','12','1','32','11','12','21','3','31']
def transform(in_list, other_list):
if len(in_list) != len(other_list):
raise ValueError("Lists must have the sema length!")
out_list = list()
out_other_list = list()
for i, c in enumerate(in_list):
for inner_list, inner_other_list in zip(out_list, out_other_list):
if c in inner_list:
inner_list.append(c)
inner_other_list.append(other_list[i])
break
else:
out_list.append([c])
out_other_list.append([other_list[i]])
return out_list, out_other_list
print transform(list1, list2)
Though I personally like soon's answer,This one successfully retrieve your desired output.
lst= sorted(zip(list1,list2),key=lambda x:x[0])
intList=[]
initial=lst[0][0]
count=0
for index,value in enumerate(lst):
if value[0]==initial:
continue
else:
intList.append(lst[count:index])
initial=value[0]
count=index
finList1=[[a for a,b in innerList] for innerList in intList]
finList2=[[b for a,b in innerList] for innerList in intList]

Sorting columns in a table (list of lists) whilst preserving the correspondence of the rows

For example:
list1 = ['c', 'b', 'a']
list2 = [3, 2, 1]
list3 = ['11', '10', '01']
table = [list1, list2, list3]
I'd like to sort with respect to the first column (list1), but I'd like the final ordering to still preserve the lines (so after sorting I'd still have a line 'b', 2, '10'). In this example I could just sort each list individually but with my data I can't just do that. What's the pythonic approach?
One quick way would be to use zip:
>>> from operator import itemgetter
>>> transpose = zip(*table)
>>> transpose.sort(key=itemgetter(0))
>>> table = zip(*transpose)
>>> table
[('a', 'b', 'c'), (1, 2, 3), ('01', '10', '11')]
# Get a list of indexes (js), sorted by the values in list1.
js = [t[1] for t in sorted((v,i) for i,v in enumerate(list1))]
# Use those indexes to build your new table.
sorted_table = [[row[j] for j in js] for row in table]
See this question for information on how Python sorts a list of tuples.

Categories