I want to cast set in list to list like below.
before: [(1, 1, 1), (1, 1, 0), (1, 0, 1)]
after: [[1, 1, 1], [1, 1, 0], [1, 0, 1]]
I need the as simple code as possible.
>>> x = [(1, 1, 1), (1, 1, 0), (1, 0, 1)]
>>> list(map(list, x))
[[1, 1, 1], [1, 1, 0], [1, 0, 1]]
Explanation
map(list, x) takes an iterable x and applies function list to each element of this iterable. Thus the tuple (1, 1, 1) becomes the list [1, 1, 1], (1, 1, 0) becomes [1, 1, 0] and (1, 0, 1) becomes [1, 0, 1].
These lists are then stored in a map object (assuming Python 3.x). A map object is an iterator, which can be converted to a list by calling list on it, as shown above. Often, though, you don't need to make this explicit conversion because iterator allows you to traverse the elements directly:
>>> for elem in map(list, x):
... print(elem)
...
[1, 1, 1]
[1, 1, 0]
[1, 0, 1]
Let's define "before" as a variable called "array". Then we take the for-loop of the "array" while casting each element to a list.
array = [(1,1,1), (1,1,0), (1,0,1)]
casted_array = []
for tuples in array:
casted_array.append(list(tuples))
There are slightly easier ways to do this, but they are harder to understand. Explanation: You define the list [(1,1,1), (1,1,0), (1,0,1)] as a variable and then define a "dummy" variable called "casted_array". You then loop through the items in the "array" variable while saving them to the "tuples" iteration variable. Every time the iteration cycle loops, the sets/tuples are converted into lists and then added on to the "casted_array" variable. The casted set/tuple is now stored in the "casted_array" variable.
Related
In Python, I have a list of ranges like that:
A = [range(0,2),range(0,4),range(0,3),range(0,3)]
First I have to convert all of these ranges into sets. I can create an empty set and add the resulting list to it. I would have:
B = [[0, 1], [0, 1, 2, 3], [0, 1, 2], [0, 1, 2]]
But after that, I have to create all the possible combinations of elements between the lists. The set with the lowest values would be [0, 0, 0, 0] and the highest values would be: [1, 3, 2, 2]. It would be a combination of 2x4x3x3 = 72 sets. How can I achieve this result, starting with the list of ranges (A)?
You can use the built-in itertools module to take the cartesian product of all the range objects in A, and skip making B altogether:
import itertools
A = [range(2), range(4), range(3), range(3)]
list(itertools.product(*A))
Output (skipping some items for readability):
[(0, 0, 0, 0),
(0, 0, 0, 1),
(0, 0, 0, 2),
(0, 0, 1, 0),
(0, 0, 1, 1),
.
.
.
(1, 3, 2, 2)]
Verifying the length:
>>> len(list(itertools.product(*A)))
72
Note that itertools.product() yields tuple objects. If for whatever reason you'd prefer these to be lists, you can use a comprehension:
[[*p] for p in itertools.product(*A)]
Another approach, as #don'ttalkjustcode points out, is that you can avoid creating A entirely and skip directly to the cartesian product via the map() function:
list(itertools.product(*map(range, (2, 4, 3, 3))))
However, this assumes that all your ranges start at 0.
You could generalize this mapping technique by using a lambda which will create range objects from a list of tuples:
>>> list(map(lambda t: range(*t), ((6, -3, -1), (0, 3), (5,), (10, 1, -2))))
[range(6, -3, -1), range(0, 3), range(0, 5), range(10, 1, -2)]
to get the Cartesian product do the following :
A = []
for i in range(2):
for j in range(4):
for k in range(3):
for n in range(3):
combo = [i,j,k,n]
A.append(combo)
This question already has an answer here:
Numpy binary matrix - get rows and columns of True elements
(1 answer)
Closed 2 years ago.
I have a large set of data and I am trying to get it into a specific form (So i can re-use someone else's code). Here's an example of a smaller set I am working with.
>>> a = np.array([[0, 1, 2], [0, 2, 4], [0, 3, 6]])
>>> a
array([[0, 1, 2],
[0, 2, 4],
[0, 3, 6]])
>>> np.where(a==0)
(array([0, 1, 2]), array([0, 0, 0]))
So, what this returns is two arrays in a tuple.
The places that are 0 are (0,0), (1,0), and (2,0)
I'd like to get this data into this form:
[(0,0), (1,0), (2,0)]
Which is a list of tuples.
Appreciate any pointers.
Try numpy.argwhere
[tuple(x) for x in numpy.argwhere(a==0)]
list(zip(*np.where(a==0)))
How this works:
The zip function will produce a sequence of tuples, consisting of:
tuple containing element 0 from each of its arguments
tuple containing element 1 from each of its arguments
... etc..
So the elements of this sequence will be in the required form if the arguments to zip are the elements of the tuple returned by numpy.where. The use of * means to expand this tuple to separate positional parameters, as required, rather than passing in the tuple itself. It is then only necessary to call list() to iterate over the iterator returned by zip and convert the values into a list.
Example:
>>> a = np.array([[0, 1, 2], [0, 2, 4], [0, 3, 6]]) # array in the question
>>> list(zip(*np.where(a==0)))
[(0, 0), (1, 0), (2, 0)] # list of 2-tuples
>>> a = a.reshape(1,3,3) # now a 3d-array (adds slowest varying dimension of size 1)
>>> list(zip(*np.where(a==0)))
[(0, 0, 0), (0, 1, 0), (0, 2, 0)] # now you get a list of 3-tuples
You need this:
np.argwhere(a==0)
output for your example:
[[0 0]
[1 0]
[2 0]]
And if you need a list of tuples instead:
list(map(tuple,np.argwhere(a==0)))
output:
[(0, 0), (1, 0), (2, 0)]
Ok. I'm looking for the smartest and more compact way to do this function
def f():
[[a,b,c] for a in range(6) for b in range(6) for c in range(6)]
which should generate all the combinations for the values a,b,c like this:
[0,0,0]
[0,0,1]
[0,0,2]
...
[1,0,0]
[1,0,1]
...
and so on...
But I want this to be flexible, so I can change the range or iterable, and also the length of the generated arrays. Range is an easy thing:
def f(min, max):
[[a,b,c] for a in range(min,max) for b in range(min,max) for c in range(min,max)]
This is ok for 3-length arrays, but I'm thinking now of making 4-length arrays or 7-length arrays and generate all combinations for them in the same range.
It has to exist an easy way, maybe with concatenating arrays or nesting comprehension lists in some way, but my solutions seem to bee too much complex.
Sorry for such a long post.
You can use itertools.product which is just a convenience function for nested iterations. It also has a repeat-argument if you want to repeat the same iterable multiple times:
>>> from itertools import product
>>> amin = 0
>>> amax = 2
>>> list(product(range(amin, amax), repeat=3))
[(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]
To get the list of list you could use map:
>>> list(map(list, product(range(amin, amax), repeat=3)))
[[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]]
However product is an iterator so it's really efficient if you just iterate over it instead of casting it to a list. At least if that's possible in your program. For example:
>>> for prod in product(range(amin, amax), repeat=3):
... print(prod) # one example
(0, 0, 0)
(0, 0, 1)
(0, 1, 0)
(0, 1, 1)
(1, 0, 0)
(1, 0, 1)
(1, 1, 0)
(1, 1, 1)
You can use itertools.product:
from itertools import product
def f(minimum, maximum, n):
return list(product(*[range(minimum, maximum)] * n))
Drop list to return a generator for memory efficiency.
itertools has everything you need. combinations_with_replacement will generate combinations of given length with repeating elements from given iterable. Note that returned value will be iterator.
def f(min, max, num):
return itertools.combinations_with_replacement(range(min, max), num)
A pure python implementation :
k=2 # k-uples
xmin=2
xmax=5
n=xmax-xmin
l1 = [x for x in range(n**k)]
l2 = [[ x//n**(k-j-1)%n for x in l1] for j in range(k)]
l3 = [[ xmin + l2[i][j] for i in range(k)] for j in range(n**k)]
l3 is :
[[2 2]
[2 3]
[2 4]
[3 2]
[3 3]
[3 4]
[4 2]
[4 3]
[4 4]]
What you are looking for is the cartesian product of the ranges. Luckily this already exists in itertools
import itertools
print(list(itertools.product(range(0,5), range(0,5), range(0,5))))
I'm new to Python and programming in general, so I apologise if I am not doing things in the most efficient manner possible.
Suppose I have a list:
Coords = [[1, 1], [2, 1], [1, 2], [1, 1]]
And I'd like to make a new list called xCoords:
xCoords = [1, 2, 1, 1]
How may I go about doing this?
I'd like a method which is expandable, as the problem I am currently working on involves an arbitrarily long list of positions.
Thanks
One simple way would be with a list comprehension
xCoords = [i[0] for i in Coords]
You could transpose the list with zip, and then select the first row with simple indexing:
>>> Coords = [[1, 1], [2, 1], [1, 2], [1, 1]]
>>> zip(*Coords)
[(1, 2, 1, 1), (1, 1, 2, 1)]
>>> zip(*Coords)[0]
(1, 2, 1, 1)
>>> list(zip(*Coords)[0])
[1, 2, 1, 1]
This is somewhat more memory intensive than a list comprehension approach, however.
I am seeing a very unusual behavior in python.. Kindly let me know what am i doing wrong!!
bc = [[0]*(n+1)]*(n+1)
for i in range(n+1):
bc[i][i] = 1
print (bc)
Output
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
I am trying to initialize the diagonal elements of two dimensional array to 1, but it is initializing all the elements with 1. I think I am doing something wrong with accessing two dimensional Array..
Also, kindly let me know how can I use two loops to access all the elements of two dimensional array.. my next step..
Thanks.
Your array is initialized incorrectly. The correct way to initialize a 2d array is this:
bc = [[0 for i in xrange(n + 1)] for i in xrange(n + 1)]
It's a common mistake, but the * operator copies the pointer to an list rather than copying the list, so while it looks like you have a 2d list, you actually have a 1d list of pointers to the same list.
the problem is that each array in your array is the same array in memory. you need a new array each time. the [[0]]*6 will for example make 6 of the same arrays in an array, editing one of them will update the other ones.
e.g.
>>> x=[1]
>>> y=x
>>> x.append(3)
>>> x
[1, 3]
>>> y
[1, 3]
>>> z=[x]*3
>>> x.append(6)
>>> z
[[1, 3, 4, 6], [1, 3, 4, 6], [1, 3, 4, 6]]
here is a fix by simply editing bc to be n+1 different arrays:
n=4
bc = [[0]*(n+1) for i in range(n+1)]
for i in range(n+1):
bc[i][i] = 1
print (bc)
[[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]]
Try this one:
bc = [[0 for i in range(n+1)] for j in range(n+1)]
In your example you have only one (!) instance of [0] which is referenced multiple times. So if you change that instance, all references are changed.