Consider the following code:
list_example = [1,2,3,4,5,6,7,8,9]
List_of_ball_permutations = []
for i in list_example :
for j in list_example:
if j>i:
List_of_ball_permutations.append([i,j])
This will result in a list being formed as follows:
[[1, 2],
[1, 3],
[1, 4],
[1, 5],
[1, 6],
[1, 7],
[1, 8],
[1, 9],
[2, 3],
[2, 4],
[2, 5],
[2, 6],
[2, 7],
[2, 8],
[2, 9],
[3, 4],
[3, 5],
[3, 6],
[3, 7],
[3, 8],
[3, 9],
[4, 5],
[4, 6],
[4, 7],
[4, 8],
[4, 9],
[5, 6],
[5, 7],
[5, 8],
[5, 9],
[6, 7],
[6, 8],
[6, 9],
[7, 8],
[7, 9],
[8, 9]]
Whereby each number is paired with another number in the list and no repeats i.e. if [1,2] exists then [2,1] will not be created also pairs with two of the same numbers e.g. [1,1] will not be created either.
However now consider a list of objects whereby I would like to pair each object with one other object (not itself and no repeats) in a similar fashion as the numbers were. For some reason my code does not allow me to do that as it presents a message '>' not supported between instances of 'Ball' and 'Ball'. (The class I created was called Ball which generated the objects).
Any help to resolve this issue would be very much appreciated.
Of course, itertools is the proper "pythonic" solution:
import itertools
list(itertools.combinations(["a", "b", "c"], 2))
However, you have the correct idea, you can generate all the indices of the objects to be paired, and retrieve them:
def get_pairs(n):
for i in range(n) :
for j in range(i+1, n):
yield (i, j)
def get_objects_pairs(objects):
for first, second in get_pairs(len(objects)):
yield objects[first], objects[second]
objects = ['a', 'ball', 'toothbrush']
for pair in (get_objects_pairs(objects)):
print(pair)
output:
('a', 'ball')
('a', 'toothbrush')
('ball', 'toothbrush')
Related
I have a two-dimensional list like this:
[[1, 6], [2, 5], [3, 7], [5, 2], [6, 1], [7, 3], [8, 9], [9, 8]]
I want to remove all the sublists that are duplicates but in reverse order (ie: [1, 6] and [6, 1], [3, 7] and [7, 3]).
The result should be:
[[1, 6], [2, 5], [3, 7], [8, 9]]
You can use set and frozenset:
lst = [[1, 6], [2, 5], [3, 7], [5, 2], [6, 1], [7, 3], [8, 9], [9, 8]]
output = set(map(frozenset, lst))
print(output)
# {frozenset({1, 6}), frozenset({2, 5}), frozenset({3, 7}), frozenset({8, 9})}
If you want to have a list of lists, then you can append the following:
output = list(map(list, output))
print(output)
# [[1, 6], [2, 5], [3, 7], [8, 9]]
You can do this easily by checking if the sorted list is already had already been added. Like this:
data = [[1, 6], [2, 5], [3, 7], [5, 2], [6, 1], [7, 3], [8, 9], [9, 8]]
new_data = []
for lst in data:
if sorted(lst) not in new_data:
new_data.append(lst)
print(new_data) # => [[1, 6], [2, 5], [3, 7], [8, 9]]
This works because [1, 6] and [6, 1] return the same sorted list.
I want to reshape the list Ii to (1,11,2) but I am getting an error. I present the expected output.
import numpy as np
Ii=[np.array([[0, 2],
[2, 4],
[2, 5],
[2, 6],
[3, 1],
[3, 7],
[4, 5],
[4, 6],
[5, 3],
[5, 7],
[6, 5]])]
Y=Ii[0].shape
Ii=Ii[0].reshape(1,Y)
The error is
in <module>
Ii=Ii[0].reshape(1,Y)
TypeError: 'tuple' object cannot be interpreted as an integer
The expected output is
array([[[0, 2],
[2, 4],
[2, 5],
[2, 6],
[3, 1],
[3, 7],
[4, 5],
[4, 6],
[5, 3],
[5, 7],
[6, 5]]])
np.newaxis can be used here to reshape the array.
Ii[0][np.newaxis,:]
or you can use reshaping after unpacking tuple.
Ii[0].reshape([1, *Y])
Try this:
Ii = Ii[0].reshape(1, Y[0], Y[1])
If I have a dictionary say:
dictionary = {'blue': [ [0,1], [0,2] ] , 'red': [ [0,3], [0,4] ] }
How would I move a blue value say [0,1] to the red without leaving behind a copy in blue without hardcoding the delete ( so if I had a different list of a hundred values and want to move a value from one key to another it should also work in that way ).
I want the output to look this:
dictionary = {'blue': [ [0,2] ] , 'red': [ [0,3], [0,4], [0,1] ] }
EDIT:
Ok, since people are asking for context:
My dictionary is:
d = {' . ': [[0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [0, 7], [0, 8], [0, 9], [1, 1],
[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7], [1, 8], [1, 9], [2, 1], [2, 2],
[2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [2, 8], [2, 9], [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]],
' X ': [[0, 0], [1, 0], [2, 0], [3, 0]]}
I want to move [3,0] from ' X ' to ' . ' and don't want it being left behind there.
I don't want this hardcoded as I want to do so with other values back and forth.
Conditions to move values:
If a value has a certain neighbours
ie [1,0] neighbours are [0,0], [2,0], [0,1] and so on
so if it has a certain number of neighbours or doesn't I move it to either ' X ' or ' . '
This is so I can plot the coordinates with the corresponding label --> 'X' or '.'
I'm not sure if you're allowed to change the dictionary (this seems to be a homework assignment), but I think it would probably be better to store the coords as the keys and the symbols as the values of the dictionary.
# A dictionary comprehension to create a dict.
# Coords as the keys and '.' as the values.
board = {(x, y): '.' for x in range(10) for y in range(10)}
# To change the value just set some coords to 'X' or '.'.
board[(2, 3)] = 'X'
# Print the board.
for y in range(10):
for x in range(10):
print(board[(x, y)], end=' ')
print()
Maybe you could use tuples for internal lists and OrderedDict for external:
from collections import OrderedDict
dictionary = {'blue': OrderedDict.fromkeys([(0, 1), (0, 2)]),
'red': OrderedDict.fromkeys([(0, 3), (0, 4)])}
Then you could still iterate the values of the external dictionary one by one:
for pair in dictionary['blue']:
print(pair)
and inserting/deleting a pair would take O(1) on average.
Just a generic function to move values between keys. You should deal with the exception outside the function.
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
def moveBetweenKeys(dictionary, src_key, dest_key, value):
"""
Move the value <value> from the key <src_key> to the key <dest_key>
Raises ValueError if the value was not found in the list of the keywork
<src_key>
"""
src_list = dictionary[src_key]
dest_list = dictionary[dest_key]
if value not in src_list:
raise ValueError("'%s' was not found in the list '%s'" % (value, src_key))
src_list.remove(value)
dest_list.append(value)
I have a nested list as follows:
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
I need to permute only the elements inside each list.
do you have any idea how can I do this?
You can do something like this:
import random
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for x in A:
random.shuffle(x)
To shuffle each sublist in a list comprehension, you cannot use random.shuffle because it works in place. You can use random.sample with the sample length = the length of the list:
import random
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
new_a = [random.sample(l,len(l)) for l in A]
print(new_a)
an output:
[[2, 1, 3], [5, 4, 6], [7, 9, 8]]
That solution is the best one if you don't want to modify your original list. Else, using shuffle in a loop as someone else answered works fine as well.
Use permutations from itertools:
from itertools import permutations
A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
out = []
for i in A:
for j in permutations(i):
out.append(list(j))
print out
OUTPUT:
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1],
[4, 5, 6], [4, 6, 5], [5, 4, 6], [5, 6, 4], [6, 4, 5], [6, 5, 4],
[7, 8, 9], [7, 9, 8], [8, 7, 9], [8, 9, 7], [9, 7, 8], [9, 8, 7]]
I have the following lists:
[[1, 5], [3, 7], [4, 2], [7, 8], [6, 3], [2, 5], [4, 1]]
And I am trying to sort them by the first value, after making the list go in ascending order:
Desired output:
[[1, 4], [1, 5], [2, 4], [2, 5], [3, 6], [3, 7], [7, 8]]
However, list.sort() only gives the following:
>>> mylist = [[1, 5], [3, 7], [4, 2], [7, 8], [6, 3], [2, 5], [4, 1]]
>>> mylist.sort()
>>> mylist
[[1, 5], [2, 5], [3, 7], [4, 1], [4, 2], [6, 3], [7, 8]]
>>>
Of course, I could always loop each list in the list of lists and sort it:
>>> mylist
[[1, 5], [2, 5], [3, 7], [4, 1], [4, 2], [6, 3], [7, 8]]
>>> for k in range(len(mylist)):
... mylist[k] = sorted(mylist[k])
...
>>> mylist
[[1, 5], [2, 5], [3, 7], [1, 4], [2, 4], [3, 6], [7, 8]]
>>> sorted(mylist)
[[1, 4], [1, 5], [2, 4], [2, 5], [3, 6], [3, 7], [7, 8]]
But is there a one liner to solve this?
You can do:
sorted(sorted(sublist) for sublist in mylist)
This is a little better than your loop:
for sublist in mylist:
sublist.sort()
mylist.sort()
Of course, this changes each sublist in-place. Judging by your examples, it looks like that is what you want, but I thought I should mention it just in case.
Here is a one liner that does the sort in-place
>>> mylist = [[1, 5], [3, 7], [4, 2], [7, 8], [6, 3], [2, 5], [4, 1]]
>>> mylist.sort(key=lambda x:x.sort() or x)
>>> mylist
[[1, 4], [1, 5], [2, 4], [2, 5], [3, 6], [3, 7], [7, 8]]