This question already has answers here:
Expanding tuples into arguments
(5 answers)
Closed 6 years ago.
Python itertools.product() takes coma separated 1D lists and returns a product. I have a list of divisors of a number in a form
l=[[1, a1**1,a1**2,..a1**b1],[1,a2**1,..a2**b2],..[1, an**1, an**2,..an**bn]]
When I pass it to itertools.product() as an argument I don't get the desired result. How can I feed this list of lists of integers to product()?
import itertools
print([list(x) for x in itertools.product([1,2,4],[1,3])])
# [[1, 1], [1, 3], [2, 1], [2, 3], [4, 1], [4, 3]] #desired
l1=[1,2,4],[1,3] #doesn't work
print([list(x) for x in itertools.product(l1)])
#[[[1, 2, 4]], [[1, 3]]]
l2=[[1,2,4],[1,3]] #doesn't work
print([list(x) for x in itertools.product(l2)])
#[[[1, 2, 4]], [[1, 3]]]
You need to use *l2 within the product() as * unwraps the list. In this case, the value of *[[1,2,4],[1,3]] will be [1,2,4],[1,3]. Here's your code:
l2 = [[1,2,4],[1,3]]
print([list(x) for x in itertools.product(*l2)])
# Output: [[1, 1], [1, 3], [2, 1], [2, 3], [4, 1], [4, 3]]
Please check: What does asterisk mean in python. Also read regarding *args and **kwargs, you might find it useful. Check: *args and **kwargs in python explained
Related
This question already has answers here:
How do I make a flat list out of a list of lists?
(34 answers)
Closed last month.
for example, I get
[[], [2, 3, 4, 5]]
[[1], [3, 4, 5]]
[[1, 2], [4, 5]]
[[1, 2, 3], [5]]
[[1, 2, 3, 4], []]
And I want to convert first list into [2,3,4,5], next [1,3,4,5], et cetera.
I try to mutiply them all together but of course a list cannot mutiply a interger.
You can use itertools.chain:
>>> from itertools import chain
>>> list(chain.from_iterable([[1, 2], [4, 5]]))
[1, 2, 4, 5]
I have a dictionary, each key of dictionary has a list of list (nested list) as its value. What I want is imagine we have:
x = {1: [[1, 2], [3, 5]], 2: [[2, 1], [2, 6]], 3: [[1, 5], [5, 4]]}
My question is how can I access each element of the dictionary and concatenate those with same index: for example first list from all keys:
[1,2] from first keye +
[2,1] from second and
[1,5] from third one
How can I do this?
You can access your nested list easily when you're iterating through your dictionary and append it to a new list and the you apply the sum function.
Code:
x={1: [[1,2],[3,5]] , 2:[[2,1],[2,6]], 3:[[1,5],[5,4]]}
ans=[]
for key in x:
ans += x[key][0]
print(sum(ans))
Output:
12
Assuming you want a list of the first elements, you can do:
>>> x={1: [[1,2],[3,5]] , 2:[[2,1],[2,6]], 3:[[1,5],[5,4]]}
>>> y = [a[0] for a in x.values()]
>>> y
[[1, 2], [2, 1], [1, 5]]
If you want the second element, you can use a[1], etc.
The output you expect is not entirely clear (do you want to sum? concatenate?), but what seems clear is that you want to handle the values as matrices.
You can use numpy for that:
summing the values
import numpy as np
sum(map(np.array, x.values())).tolist()
output:
[[4, 8], [10, 15]] # [[1+2+1, 2+1+5], [3+2+5, 5+6+4]]
concatenating the matrices (horizontally)
import numpy as np
np.hstack(list(map(np.array, x.values()))).tolist()
output:
[[1, 2, 2, 1, 1, 5], [3, 5, 2, 6, 5, 4]]
As explained in How to iterate through two lists in parallel?, zip does exactly that: iterates over a few iterables at the same time and generates tuples of matching-index items from all iterables.
In your case, the iterables are the values of the dict. So just unpack the values to zip:
x = {1: [[1, 2], [3, 5]], 2: [[2, 1], [2, 6]], 3: [[1, 5], [5, 4]]}
for y in zip(*x.values()):
print(y)
Gives:
([1, 2], [2, 1], [1, 5])
([3, 5], [2, 6], [5, 4])
Please could I have help with the following query in Python 3.9.
I have the following sublists:
[0, 1]
[1, 3]
[2, 5]
I would like to make a new list with each of these sublists repeated a different number of times. Required output:
[[0,1],[0,1],[0,1],[1,3],[1,3],[2,5],[2,5],[2,5],[2,5]]
I have tried doing the following:
[[[0,1]]*3,[[1,3]]*2,[[2,5]]*4]
However I get this:
[[[0,1],[0,1],[0,1]],[[1,3],[1,3]],[[2,5],[2,5],[2,5],[2,5]]]
How do I get my desired output? Or alternatively, how do I just flatten it by one level? Thank you
You can just unpack the sublists:
[*[[0,1]]*3, *[[1,3]]*2, *[[2,5]]*4]
# [[0, 1], [0, 1], [0, 1], [1, 3], [1, 3], [2, 5], [2, 5], [2, 5], [2, 5]]
Note however, that the resulting sublists are not independent, but references to the same list objects (changes made to one sublist will be reflected in all the equal others)! Better use generators/comprehensions:
[*([0,1] for _ in range(3)),
*([1,3] for _ in range(2)),
*([2,5] for _ in range(4))]
# [[0, 1], [0, 1], [0, 1], [1, 3], [1, 3], [2, 5], [2, 5], [2, 5], [2, 5]]
The more general question of 1-level flattening has been asked and answered multiple times, but the main options are the nested comprehension:
[x for sub in lst for x in sub]
or itertools.chain:
[*chain(lst)]
You can use list loop:
r1 = [0, 1]
r2 = [1, 3]
r3 = [2, 5]
h = [*(r1 for x in range(3)),
*(r2 for x in range(2)),
*(r3 for x in range(4))]
print(h)
Currently, I want to find the correct data structure to meet the following requirement.
There are multiple arrays with disordered element, for example,
[1, 2], [2, 1], [3, 2, 2], [2], [2, 1, 3], [2, 2, 3]
After processing those data, the result is,
[1, 2], [2, 2, 3], [2], [1, 2, 3]
With sorted element in each array and filter the duplicate arrays.
Here are my thoughts:
Data structure Set(Arrays)? - Failed. It seems there is only one array in the build-in set
set([])
Data structure Array(Sets)? - Failed. However, there is no duplicate element in the build-in set. I want to know whether there is one data structure like multiset in C++ within Python?
Transform your list to tuple(thus can be a item of set), then back to list.
>>> [list(i) for i in set([tuple(sorted(i)) for i in a])]
[[1, 2], [2], [2, 2, 3], [1, 2, 3]]
lst = [[1, 2], [2, 1], [3, 2, 2], [2], [2, 1, 3], [2, 2, 3]]
map(list, set(map(tuple, map(sorted, lst)))
Output:
[[1, 2], [2], [2, 2, 3], [1, 2, 3]]
Try this:
[list(i) for i in set(map(tuple, a))]
EDIT:
Assuming that list is already sorted. Thanks to #PM2RING to remind me.
If not, then add this line above
a = [sorted(i) for i in a]
Thanks again to #PM2RING: one liner
[list(i) for i in set(map(tuple, (sorted(i) for i in a)))]
Demo
Some of the solutions currently here are destroying ordering. I'm not sure if that's important to you or not, but here is a version which preserves original ordering:
>>> from collections import OrderedDict
>>> A = [[1, 2], [2, 1], [3, 2, 2], [2], [2, 1, 3], [2, 2, 3]]
>>> [list(k) for k in OrderedDict.fromkeys(tuple(sorted(a)) for a in A)]
[[1, 2], [2, 2, 3], [2], [1, 2, 3]]
No Python, doesn't have a built-in multiset; the closest equivalent in the standard modules is collections.Counter, which is a type of dictionary. A Counter may be suitable for your needs, but it's hard to tell without more context.
Note that sets do not preserve order of addition. If you need to preserve the initial ordering of the lists, you can do what you want like this:
data = [[1, 2], [2, 1], [3, 2, 2], [2], [2, 1, 3], [2, 2, 3]]
a = set()
outlist = []
for s in data:
t = tuple(sorted(s))
if t not in a:
a.add(t)
outlist.append(list(t))
print(outlist)
output
[[1, 2], [2, 2, 3], [2], [1, 2, 3]]
If the number of input lists is fairly small you don't need the set (and the list<->tuple conversions), just test membership in outlist. However, that's not efficient for larger input lists since it performs a linear search on the list.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to generate all permutations of a list in Python
I am given a list [1,2,3] and the task is to create all the possible permutations of this list.
Expected output:
[[1, 2, 3], [1, 3, 2], [2, 3, 1], [2, 1, 3], [3, 1, 2], [3, 2, 1]]
I can't even think from where to begin. Can anyone help?
Thanks
itertools.permutations does this for you.
Otherwise, a simple method consist in finding the permutations recursively: you successively select the first element of the output, then ask your function to find all the permutations of the remaining elements.
A slightly different, but similar solution can be found at https://stackoverflow.com/a/104436/42973. It finds all the permutations of the remaining (non-first) elements, and then inserts the first element successively at all the possible locations.
this is a rudimentary solution...
the idea is to use recursion to go through all permutation and reject the non valid permutations.
def perm(list_to_perm,perm_l,items,out):
if len(perm_l) == items:
out +=[perm_l]
else:
for i in list_to_perm:
if i not in perm_l:
perm(list_to_perm,perm_l +[i],items,out)
a = [1,2,3]
out = []
perm(a,[],len(a),out)
print out
output:
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]