Related
How could I write this in an eaiser way?
product_pairs =
[[(1, 2), (1, 3), (1, 6), (1, 8), (1, 9), (2, 3), (2, 6), (2, 8), (2, 9), (3, 6), (3,
8), (3, 9), (6, 8), (6, 9), (8, 9)],
[(0, 5), (0, 9), (5, 9)],
[(0, 9)],
[(0, 4), (0, 5), (0, 7), (0, 9), (4, 5), (4, 7), (4, 9), (5, 7), (5, 9), (7, 9)],
[(3, 8)],
[(1, 3), (1, 6), (1, 8), (3, 6), (3, 8), (6, 8)],
[(0, 5), (0, 9), (5, 9)],
[(3, 8)],
[(0, 4), (0, 5), (0, 7), (4, 5), (4, 7), (5, 7)],
[(0, 1), (0, 2), (0, 3), (0, 6), (1, 2), (1, 3), (1, 6), (2, 3), (2, 6), (3, 6)]]
cooccurences={}
d={}
pairs=[]
for lists in product_pairs:
for pair in lists:
if pair not in pairs: # If the pair is not in the dictionary
pairs.append(pair) # Storing all the pairs in a list
d[pair]=1 # Adding to the dictionary with value 1
else: # If the pair is already in the dictionary
d[pair]+=1 # Incrementing its value by 1
pairs.sort() # Sorting the pairs list
for pair in pairs: # Iterating through all pairs in sorted order
cooccurences[pair]=d[pair] # Storing their value in a dictionary
print(cooccurences) # Displaying output
Output:
{(0, 1): 1, (0, 2): 1, (0, 3): 1, (0, 4): 2, (0, 5): 4, (0, 6): 1, (0, 7): 2, (0, 9): 4, (1, 2): 2, (1, 3): 3, (1, 6): 3, (1, 8): 2, (1, 9): 1, (2, 3): 2, (2, 6): 2, (2, 8): 1, (2, 9): 1, (3, 6): 3, (3, 8): 4, (3, 9): 1, (4, 5): 2, (4, 7): 2, (4, 9): 1, (5, 7): 2, (5, 9): 3, (6, 8): 2, (6, 9): 1, (7, 9): 1, (8, 9): 1}
Best done using collections.Counter (also take a look at collections.defaultdict for a slightly more "manual" approach):
from collections import Counter
counter = Counter(pair for product_list in product_pairs for pair in product_list)
print(dict(counter.most_common()))
I need to make couple for elements from two lists (two lists are different size)
Ex:
x = ([3,2], [4,6,-8])
y = ([-5,1,4], [13,9], [7,5,-1,10])
Result:
new_list = ([3, -5], [3, 1], [3, 4], [3, 13], [3, 9], [3, 7], [3, 5], [3, -1],[3, 10], [2, -5], [2, 1] ......<sorry, there're too many>.... [-8, 5], [-8, -1], [-8, 10])
Thanks for support!
In two steps, 1) flatten your list of lists, 2) itertools.product
Flatten your list of lists:
How to make a flat list out of a list of lists
flat_list = itertools.chain(*iterable_of_lists)
Use itertools to create the product of the two lists.
itertools.product(x, y)
Example from OP:
import itertools
x = ([3,2], [4,6,-8])
y = ([-5,1,4], [13,9], [7,5,-1,10])
x_flat = itertools.chain(*x)
y_flat = itertools.chain(*y)
list(itertools.product(x_flat, y_flat))
result:
[(3, -5), (3, 1), (3, 4), (3, 13), (3, 9), (3, 7), (3, 5), (3, -1), (3, 10), (2, -5), (2, 1), (2, 4), (2, 13), (2, 9), (2, 7), (2, 5), (2, -1), (2, 10), (4, -5), (4, 1), (4, 4), (4, 13), (4, 9), (4, 7), (4, 5), (4, -1), (4, 10), (6, -5), (6, 1), (6, 4), (6, 13), (6, 9), (6, 7), (6, 5), (6, -1), (6, 10), (-8, -5), (-8, 1), (-8, 4), (-8, 13), (-8, 9), (-8, 7), (-8, 5), (-8, -1), (-8, 10)]
Your x, y and new_list in the examples are actually tuples and not lists, because you use () instead of [].
Based on your expected result, I assume that you don't really need lists of lists here, you just take flat lists:
x = [3,2,4,6,-8]
y = [-5,1,4,13,9,7,5,-1,10]
And find each combination between x and y. Which can be done using itertools.product
Using itertools chain and product:
from itertools import product, chain
new_list = list(product(chain(*x), chain(*y)))
[(3, -5), (3, 1), (3, 4), (3, 13), (3, 9), (3, 7), (3, 5), (3, -1), (3, 10), (2, -5), (2, 1), (2, 4), (2, 13), (2, 9), (2, 7), (2, 5), (2, -1), (2, 10), (4, -5), (4, 1), (4, 4), (4, 13), (4, 9), (4, 7), (4, 5), (4, -1), (4, 10), (6, -5), (6, 1), (6, 4), (6, 13), (6, 9), (6, 7), (6, 5), (6, -1), (6, 10), (-8, -5), (-8, 1), (-8, 4), (-8, 13), (-8, 9), (-8, 7), (-8, 5), (-8, -1), (-8, 10)]
First of all you have two tuples containing lists, not lists of numbers and the expected result is a tuple containing two-length lists. So, you have to convert those tuples of lists to simple tuples first, following this solution (with a little change): https://stackoverflow.com/a/952952/11882999
x = ([3,2], [4,6,-8])
y = ([-5,1,4], [13,9], [7,5,-1,10])
x_tuple = tuple(item for sublist in x for item in sublist)
y_tuple = tuple(item for sublist in y for item in sublist)
Then following this solution (with a little change), you can calculate the combinations of two tuples easily: https://stackoverflow.com/a/39064769/11882999
result = tuple([x, y] for x in x_tuple for y in y_tuple)
>> ([3, -5], [3, 1], [3, 4], ..., [-8, 5], [-8, -1], [-8, 10])
I have the following list:
mylist: [[(5, 1, 11), (5, 2, 13), (5, 3, 26),
(3, 1, 60), (3, 2, 40), (3, 3, 70),
(6, 1, 30), (6, 2, 80), (2, 3, 80)],
[(5, 1, 7), (5, 2, 8), (5, 3, 6),
(3, 1, 50), (3, 2, 44), (3, 3, 44),
(6, 1, 20), (6, 2, 40), (2, 3, 50)],
[(5, 1, 22), (5, 2, 18), (5, 3, 60),
(3, 1, 10), (3, 2, 20), (3, 3, 30),
(6, 1, 60), (6, 2, 20), (2, 3, 30)]]
I want to calculate the average of the items which have the same "first and the second elements". E.g., from the below example, I want to take the average of the elements which have '5' and '1' in the first two elements of the list. So, my desired output should be like this:
output: [(5, 1, 13.3), (5, 2, 25.6), (5, 3, 30.6),
(3, 1, 40), (3, 2, 34.6), (3, 3, 48),
(6, 1, 36.6), (6, 2, 46.6), (6, 3, 56.6)]
If I have only two items in the lists like:
mylist: [[(1, 11), ( 2, 13), ( 3, 26),
[( 1, 60), ( 2, 40), ( 3, 70)],...]
I could easily calculate the average by the below code:
np.mean(mylist, axis=0)
see below
from collections import defaultdict
lst = [[(5, 1, 11), (5, 2, 13), (5, 3, 26),
(3, 1, 60), (3, 2, 40), (3, 3, 70),
(6, 1, 30), (6, 2, 80), (2, 3, 80)],
[(5, 1, 7), (5, 2, 8), (5, 3, 6),
(3, 1, 50), (3, 2, 44), (3, 3, 44),
(6, 1, 20), (6, 2, 40), (2, 3, 50)],
[(5, 1, 22), (5, 2, 18), (5, 3, 60),
(3, 1, 10), (3, 2, 20), (3, 3, 30),
(6, 1, 60), (6, 2, 20), (2, 3, 30)]]
data = defaultdict(list)
for ex_entry in lst:
for in_entry in ex_entry:
data[(in_entry[0], in_entry[1])].append(in_entry[2])
for key, value in data.items():
print(f'{key} -> {sum(value) / len(value)}')
output
(5, 1) -> 13.333333333333334
(5, 2) -> 13.0
(5, 3) -> 30.666666666666668
(3, 1) -> 40.0
(3, 2) -> 34.666666666666664
(3, 3) -> 48.0
(6, 1) -> 36.666666666666664
(6, 2) -> 46.666666666666664
(2, 3) -> 53.333333333333336
I have a list of tuples:
self.gridKeys = self.gridMap.keys() # The keys of the instance of the GridMap (It returns the product of every possible combination of positions in the specified grid, in tuples.)
print self.gridKeys
self.gridKeys:
[(7, 3), (6, 9), (0, 7), (1, 6), (3, 7), (2, 5), (8, 5), (5, 8), (4, 0), (9, 0), (6, 7), (5, 5), (7, 6), (0, 4), (1, 1), (3, 2), (2, 6), (8, 2), (4, 5), (9, 3), (6, 0), (7, 5), (0, 1), (3, 1), (9, 9), (7, 8), (2, 1), (8, 9), (9, 4), (5, 1), (7, 2), (1, 5), (3, 6), (2, 2), (8, 6), (4, 1), (9, 7), (6, 4), (5, 4), (7, 1), (0, 5), (1, 0), (0, 8), (3, 5), (2, 7), (8, 3), (4, 6), (9, 2), (6, 1), (5, 7), (7, 4), (0, 2), (1, 3), (4, 8), (3, 0), (2, 8), (9, 8), (8, 0), (6, 2), (5, 0), (1, 4), (3, 9), (2, 3), (1, 9), (8, 7), (4, 2), (9, 6), (6, 5), (5, 3), (7, 0), (6, 8), (0, 6), (1, 7), (0, 9), (3, 4), (2, 4), (8, 4), (5, 9), (4, 7), (9, 1), (6, 6), (5, 6), (7, 7), (0, 3), (1, 2), (4, 9), (3, 3), (2, 9), (8, 1), (4, 4), (6, 3), (0, 0), (7, 9), (3, 8), (2, 0), (1, 8), (8, 8), (4, 3), (9, 5), (5, 2)]
After sorting:
self.gridKeys = self.gridMap.keys() # The keys of the instance of the GridMap (It returns the product of every possible combination of positions in the specified grid, in tuples.)
self.gridKeys.sort() # They're dicts, so they need to be properly ordered for further XML-analysis.
print self.gridKeys
self.gridKeys:
[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (5, 7), (5, 8), (5, 9), (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6), (6, 7), (6, 8), (6, 9), (7, 0), (7, 1), (7, 2), (7, 3), (7, 4), (7, 5), (7, 6), (7, 7), (7, 8), (7, 9), (8, 0), (8, 1), (8, 2), (8, 3), (8, 4), (8, 5), (8, 6), (8, 7), (8, 8), (8, 9), (9, 0), (9, 1), (9, 2), (9, 3), (9, 4), (9, 5), (9, 6), (9, 7), (9, 8), (9, 9)]
The first element of each tuple is the "x", and the second the "y". I'm moving objects in a list through iteration and using these keys (So, if I want to move something in the x axis, I have to go through all the column, and that might be causing a horrid problem that I'm not being able to solve).
How can I sort the tuples in this way?:
[(1, 0), (2, 0), (3, 0), (4, 0), (5, 0), ...]
You can use the key parameter of the sort function, to sort the tuples. The function of key parameter, is to come up with a value which has to be used to compare two objects. So, in your case, if you want the sort to use only the first element in the tuple, you can do something like this
self.gridKeys.sort(key=lambda x: x[0])
If you want to use only the second element in the tuple, then
self.gridKeys.sort(key=lambda x: x[1])
sort function will pass each and every element in the list to the lambda function you pass as parameter to key and it will use the value it returns, to compare two objects in the list. So, in your case, lets say you have two items in the list like this
data = [(1, 3), (1, 2)]
and if you want to sort by the second element, then you would do
data.sort(key=lambda x: x[1])
First it passes (1, 3) to the lambda function which returns the element at index 1, which is 3 and that will represent this tuple during the comparison. The same way, 2 will be used for the second tuple.
This should do the trick
import operator
self.gridKeys.sort(key=operator.itemgetter(1))
While thefourtheye's solution is correct in the strict sense that it is exactly what you asked for in the title. It may not be actually what you want. It may be better to take it a bit farther via sorting by the reverse of the tuple instead.
self.gridKeys.sort(key=lambda x:tuple(reversed(x)))
This forces you to have an ordering like:
[(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), ...]
Rather than having the first element be unordered like:
[(4, 0), (9, 0), (6, 0), (1, 0), (3, 0), ...]
Which is what I get when using:
self.gridKeys.sort(key=lambda x: x[1])
By default Python does a lexicographical sort from left to right. Reversing the tuple effectively makes Python do the lexicographical sort from right to left.
I am truly a novice in Python. Now, I am doing a project which involves creating a list of 2D coordinates. The coordinates should be uniformly placed, using a square grid (10*10), like(0,0)(0,1)(0,2)(0,3)...(0,10)(1,0)(1,2)(1,3)...(2,0)(2,1)(2,2)...(10,10).
Here is my code:
coordinate = []
x = 0
y = 0
while y < 10:
while x < 10:
coordinate.append((x,y))
x += 1
coordinate.append((x,y))
y += 1
print(coordinate)
But I can only get: [(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0), (7, 0), (8, 0), (9, 0), (10, 0), (10, 1), (10, 2), (10, 3), (10, 4), (10, 5), (10, 6), (10, 7), (10, 8), (10, 9)]
How can I rewrite my code to get all the points?
It's common to use a couple of for-loops to achieve this:
coordinates = []
for x in range(11):
for y in range(11):
coordinates.append((x, y))
It's also common to simplify this by flattening it into a list comprehension:
coordinates = [(x,y) for x in range(11) for y in range(11)]
from itertools import product
x = (0, 1, 2)
test = product(x, x)
Result:
>>> for ele in test:
... print ele
...
(0, 0)
(0, 1)
(0, 2)
(1, 0)
(1, 1)
(1, 2)
(2, 0)
(2, 1)
(2, 2)
Note that test is a generator, so you probably would want to use list(test).
To actually answer your question, you forgot to reset x back to zero after the first run through x=0..9:
coordinate = []
y = 0
while y < 10:
x = 0
while x < 10:
coordinate.append((x,y))
x += 1
coordinate.append((x,y))
y += 1
print(coordinate)
Feel free to use all other variants, of course.
Use itertools.product:
>>> from itertools import product
>>> list(product(range(11), repeat=2))
[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (0, 10), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (1, 10), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (2, 10), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (3, 10), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (4, 10), (5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (5, 7), (5, 8), (5, 9), (5, 10), (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6), (6, 7), (6, 8), (6, 9), (6, 10), (7, 0), (7, 1), (7, 2), (7, 3), (7, 4), (7, 5), (7, 6), (7, 7), (7, 8), (7, 9), (7, 10), (8, 0), (8, 1), (8, 2), (8, 3), (8, 4), (8, 5), (8, 6), (8, 7), (8, 8), (8, 9), (8, 10), (9, 0), (9, 1), (9, 2), (9, 3), (9, 4), (9, 5), (9, 6), (9, 7), (9, 8), (9, 9), (9, 10), (10, 0), (10, 1), (10, 2), (10, 3), (10, 4), (10, 5), (10, 6), (10, 7), (10, 8), (10, 9), (10, 10)]
The above code is equivalent to this nested list comprehension:
>>> [(x, y) for x in range(11) for y in range(11)]
[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (0, 10), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (1, 10), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (2, 10), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (3, 10), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (4, 10), (5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (5, 7), (5, 8), (5, 9), (5, 10), (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6), (6, 7), (6, 8), (6, 9), (6, 10), (7, 0), (7, 1), (7, 2), (7, 3), (7, 4), (7, 5), (7, 6), (7, 7), (7, 8), (7, 9), (7, 10), (8, 0), (8, 1), (8, 2), (8, 3), (8, 4), (8, 5), (8, 6), (8, 7), (8, 8), (8, 9), (8, 10), (9, 0), (9, 1), (9, 2), (9, 3), (9, 4), (9, 5), (9, 6), (9, 7), (9, 8), (9, 9), (9, 10), (10, 0), (10, 1), (10, 2), (10, 3), (10, 4), (10, 5), (10, 6), (10, 7), (10, 8), (10, 9), (10, 10)]
Use a for loop. It lets you iterate over things called "iterators". range is a built-in function which returns an iterator from its starting argument (first argument) inclusive. up to its ending argument (second argument) non-inclusive. Thus range(0,11) will return 0,1,2,...,10.
coordinate = []
for y in range(0, 11):
for x in range(0, 11):
coordinate.append((x,y))
print(coordinate)
For more information on for loops in Python, check out the official wiki page.