I have a list that I create by parsing some text.
Let's say the list looks like
charlist = ['a', 'b', 'c']
I would like to take the following list
numlist = [3, 2, 1]
and join it together so that my combined list looks like
[['a', 3], ['b', 2], ['c', 1]]
is there a simple method for this?
If you want a list of lists rather than a list of tuples you could use:
map(list,zip(charlist,numlist))
The zip builtin function should do the trick.
Example from the docs:
>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> zipped = zip(x, y)
>>> zipped
[(1, 4), (2, 5), (3, 6)]
Here's another easy way to do it.
charlist = ['a', 'b', 'c']
numlist = [3, 2, 1]
newlist = []
for key, a in enumerate(charlist):
newlist.append([a,numlist[key]])
Content of newlist: [['a', 3], ['b', 2], ['c', 1]]
You could try the following, though I am sure there are going to be better approaches:
l1 = ['a', 'b', 'c']
l2 = [1, 2, 3]
l = []
for i in 1:length(l1):
l.append([l1[i], l2[i]])
All the best.
p=[]
for i in range(len(charlist)):
p.append([charlist[i],numlist[i]])
Related
I have the following list
a = [['a', 'b', 1], ['c', 'b', 3], ['c','a', 4], ['a', 'd', 2]]
and I'm trying to remove all the elements from the list where the last element is less than 3. So the output should look like
a = [['c', 'b', 3], ['c','a', 4]]
I tried to use filter in the following way
list(filter(lambda x: x == [_, _, 2], a))
Here _ tries to denote that the element in those places can be anything. I'm used to this kind of syntax from mathematica but I have been unable to find something like this in Python (is there even such a symbol in python ?).
I would prefer solution using map and filter as those are most intuitive for me.
You should be using x[-1] >= 3 in lambda to retain all sub lists with last value greater than or equal to 3:
>>> a = [['a', 'b', 1], ['c', 'b', 3], ['c','a', 4], ['a', 'd', 2]]
>>> list(filter(lambda x: x[-1] >= 3, a))
[['c', 'b', 3], ['c', 'a', 4]]
List comprehension approach:
a_new = [sublist for sublist in a if sublist[-1] >= 3]
a = [['a', 'b', 1], ['c', 'b', 3], ['c','a', 4], ['a', 'd', 2]]
Filter above list with list comprehension like:
b = [x for x in a if x[-1] >= 3]
On start I have 2 lists and 1 list that says in what order I should merge those two lists.
For example I have first list equal to [a, b, c] and second list equal to [d, e] and 'merging' list equal to [0, 1, 0, 0, 1].
That means: to make merged list first I need to take element from first list, then second, then first, then first, then second... And I end up with [a, d, b, c, e].
To solve this I just used for loop and two "pointers", but I was wondering if I can do this task more pythonic... I tried to find some functions that could help me, but no real result.
You could create iterators from those lists, loop through the ordering list, and call next on one of the iterators:
i1 = iter(['a', 'b', 'c'])
i2 = iter(['d', 'e'])
# Select the iterator to advance: `i2` if `x` == 1, `i1` otherwise
print([next(i2 if x else i1) for x in [0, 1, 0, 0, 1]]) # ['a', 'd', 'b', 'c', 'e']
It's possible to generalize this solution to any number of lists as shown below
def ordered_merge(lists, selector):
its = [iter(l) for l in lists]
for i in selector:
yield next(its[i])
In [4]: list(ordered_merge([[3, 4], [1, 5], [2, 6]], [1, 2, 0, 0, 1, 2]))
Out[4]: [1, 2, 3, 4, 5, 6]
If the ordering list contains strings, floats, or any other objects that can't be used as list indexes, use a dictionary:
def ordered_merge(mapping, selector):
its = {k: iter(v) for k, v in mapping.items()}
for i in selector:
yield next(its[i])
In [6]: mapping = {'A': [3, 4], 'B': [1, 5], 'C': [2, 6]}
In [7]: list(ordered_merge(mapping, ['B', 'C', 'A', 'A', 'B', 'C']))
Out[7]: [1, 2, 3, 4, 5, 6]
Of course, you can use integers as dictionary keys as well.
Alternatively, you could remove elements from the left side of each of the original lists one by one and add them to the resulting list. Quick example:
In [8]: A = ['a', 'b', 'c']
...: B = ['d', 'e']
...: selector = [0, 1, 0, 0, 1]
...:
In [9]: [B.pop(0) if x else A.pop(0) for x in selector]
Out[9]: ['a', 'd', 'b', 'c', 'e']
I would expect the first approach to be more efficient (list.pop(0) is slow).
How about this,
list1 = ['a', 'b', 'c']
list2 = ['d', 'e']
options = [0,1,0,0,1]
list1_iterator = iter(list1)
list2_iterator = iter(list2)
new_list = [next(list2_iterator) if option else next(list1_iterator) for option in options]
print(new_list)
# Output
['a', 'd', 'b', 'c', 'e']
This question already has answers here:
How to get the cartesian product of multiple lists
(17 answers)
Closed 7 years ago.
I have a problem like this. I have two lists, A and B, where A=[[1,2],[3,4],[5,6]] and B=[["a","b"],["c","d"]], I would like to got a new list from these two like
C = [
[[1,2],["a","b"]],
[[3,4],["a","b"]],
[[1,2],["c","d"]],
[[3,4],["c","d"]]
]
I had try the following code:
A = [[1,2],[3,4]]
B=[["a","b"],["c","d"]]
for each in A:
for evey in B:
print each.append(evey)
However, the output is None.
Any helpful information are appreciated. Thank you.
By the way, I had try to replace the "append" with simple "+". The output is a list which elements are not list.
This was answered here: Get the cartesian product of a series of lists?
Try this:
import itertools
A = [[1,2],[3,4]]
B = [["a","b"],["c","d"]]
C = []
for element in itertools.product(A,B):
C.append(list(element))
print C
This is one way to do it:
A = [[1,2],[3,4]]
B=[["a","b"],["c","d"]]
C = zip(A,B)
The output here is a list of tuples:
[([[1, 2], [3, 4]],), ([['a', 'b'], ['c', 'd']],)]
If you want a list of lists, you can do this:
D = [list(i) for i in zip(A, B)]
The output:
[[[1, 2], ['a', 'b']], [[3, 4], ['c', 'd']]]
Try this. You have to append each couple of elements in each iteration.
result = []
for each in A:
for evey in B:
result.append([each,evey])
>>>result
[[[1, 2], ['a', 'b']],
[[1, 2], ['c', 'd']],
[[3, 4], ['a', 'b']],
[[3, 4], ['c', 'd']]]
OR
simply use itertools.product
>>>from itertools import product
>>>list(product(A,B))
[([1, 2], ['a', 'b']),
([1, 2], ['c', 'd']),
([3, 4], ['a', 'b']),
([3, 4], ['c', 'd'])]
You can use itertools.product to achieve this.
import itertools
list(itertools.product(A,B)) # gives the desired result
[([1, 2], ['a', 'b']),
([1, 2], ['c', 'd']),
([3, 4], ['a', 'b']),
([3, 4], ['c', 'd']),
([5, 6], ['a', 'b']),
([5, 6], ['c', 'd'])]
itertools.product(*iterables[, repeat])
It returns the Cartesian product of input iterables
Eg.
product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
Don't print return value of append(), try this:
A = [[1,2],[3,4]]
B=[["a","b"],["c","d"]]
C = []
for each in B:
for evey in A:
C.append([evey, each])
print C
Quick Summary:
need_to_reorder = [['a', 'b', 'c', 'd'], [1, 2, 3, 4]]
I want to set an order for the need_to_reorder[0][x] x values using my sorting array
sorting_array = [1, 3, 0, 2]
Required result: need_to_reorder will equal
[['b', 'd', 'a', 'c'], [2, 4, 1, 3]]
Searching for the answer, I tried using numPy:
import numpy as np
sorting_array = [1, 3, 0, 2]
i = np.array(sorting_array)
print i ## Results: [1 3 0 2] <-- No Commas?
need_to_reorder[:,i]
RESULTS:
TypeError: list indicies must be integers, not tuple
I'm looking for a correction to the code above or an entirely different approach.
You can try a simple nested comprehension
>>> l = [['a', 'b', 'c', 'd'], [1, 2, 3, 4]]
>>> s = [1, 3, 0, 2]
>>> [[j[i] for i in s] for j in l]
[['b', 'd', 'a', 'c'], [2, 4, 1, 3]]
If you need this as a function you can have a very simple function as in
def reorder(need_to_reorder,sorting_array)
return [[j[i] for i in sorting_array] for j in need_to_reorder]
Do note that this can be solved using map function also. However in this case, a list comp is preferred as the map variant would require a lambda function. The difference between map and a list-comp is discussed in full length in this answer
def order_with_sort_array(arr, sort_arr):
assert len(arr) == len(sort_arr)
return [arr[i] for i in sort_arr]
sorting_array = [1, 3, 0, 2]
need_to_reorder = [['a', 'b', 'c', 'd'], [1, 2, 3, 4]]
after_reordered = map(lambda arr : order_with_sort_array(arr, sorting_array),
need_to_reorder)
This should work
import numpy as np
ntr = np.array([['a', 'b', 'c', 'd'], [1, 2, 3, 4]])
sa = np.array([1, 3, 0, 2])
print np.array( [ntr[0,] , np.array([ntr[1,][sa[i]] for i in range(sa.shape[0])])] )
>> [['a' 'b' 'c' 'd'],['2' '4' '1' '3']]
I am using the following code to build a list of lists:
res = []
for i in I:
res.append(x)
res.append(y[i])
so my final list is [x, y[0], x, y[1],...] where x and y[i] are also lists.
Is there a way building this list using list comprehensions, instead of for loop?
I ... think ... this might be close to what you want:
res = [z for z in ((x, y[i]) for i in I)]
Itertools can help with this sort of thing:
>>> y = I = range(5)
>>> x = 'x'
>>> res = list(itertools.chain.from_iterable((x, y[i]) for i in I))
>>> res
['x', 0, 'x', 1, 'x', 2, 'x', 3, 'x', 4]
res = reduce(tuple.__add__, [(x, y[i]) for i in I])
The map style:
res = []
map(res.extend, ((x, y[i]) for i in I))
The reduce style:
res = reduce(lambda arr, i: arr + [x, y[i]], I, [])
sum(([x, y[i]] for i in I), [])
Like bpgergo's, but with lists, and with a simpler way of joining them together.
I think this should do what you are looking for:
>>> from itertools import chain, izip, repeat
>>> x = [1, 2]
>>> y = [['a', 'b'], ['c', 'd']]
>>> list(chain(*izip(repeat(x), y)))
[[1, 2], ['a', 'b'], [1, 2], ['c', 'd']]
Note that this will have shallow copies of the inner lists (same as other solutions), so make sure you understand the following behavior:
>>> z = list(chain(*izip(repeat(x), y)))
>>> z
[[1, 2], ['a', 'b'], [1, 2], ['c', 'd']]
>>> x.append(3)
>>> z
[[1, 2, 3], ['a', 'b'], [1, 2, 3], ['c', 'd']]
>>> z[0].append(4)
>>> z
[[1, 2, 3, 4], ['a', 'b'], [1, 2, 3, 4], ['c', 'd']]
>>> y[1].append('e')
>>> z
[[1, 2, 3, 4], ['a', 'b'], [1, 2, 3, 4], ['c', 'd', 'e']]