Related
Suppose I have a dictionary that has tuplets as keys and lists of tuples as values, for example:
d={(0,1):[(1,1)],
(0,2):[(1,1),(1,2)],
(0,3):[(1,1),(1,2),(1,3)]}
I would like to remove all entries such that their value is contained in the value of another key, for example:
from d I would like to remove the entry with key (0,1) because the (1,1) is contained in [(1,1),(1,2)]
and remove the entry with key (0,2) because [(1,1),(1,2)] is contained in [(1,1),(1,2),(1,3)].
Order of tuples in the lists matters.
I can solve this using a bunch of for loops, like this:
for key, val in d.items():
for k,v in d.items():
for i in range(0, len(val)):
if val[i] in v and len(v) - len(val) == 1:
del_me = True
else:
del_me = False
break
if del_me:
to_del.append(key)
for key in set(to_del):
del d[key]
edit: (further explanation)
Keys are not important here but will be important later.
In other words:
let a,b,c,d denote unique tuples
let k1,k2,..., denote keys
lets have the entries:
k1:[a],
k2:[d],
k3:[a,b],
k4:[b,a],
k5:[a,b,c],
I want to end up with:
k2,k4,k5
Removed entries will be:
k1 because a is in k3
k3 because a,b is in k5
It hurts my eyes when I'm looking at this, sorry.
What would be a pythonic way to do this?
Let's say that you have an dictionary that looks like as follows:
d={(0,1):[(1,1)],(0,2):[(1,1),(1,2)],(0,3):[(1,1),(1,2),(1,3)],(0,4):[(1,1),(1,2),(1,4)]}
Now you want to compare the values against all the keys with one another. I suggest you place all the values in this dictionary in a list.
mylist=[]
for key in d.keys():
mylist.append(d[key])
print(mylist)
mylist will look like as follows having all the values of the dictionary.
[[(1, 1)], [(1, 1), (1, 2)], [(1, 1), (1, 2), (1, 3)], [(1, 1), (1, 2), (1, 4)]]
Now you want to compare all these values with one another and remove those values that are the subsets of any of those values. Like in this example, [(1,1)] is the subset of [(1,1),(1,2)] and so [(1,1)] will be removed. Similarly, [(1,1),(1,2)] is the subset of [(1,1),(1,2),(1,3)] and so it will also be removed. We can accomplish this as follows:
out = []
for k, elm in enumerate(mylist):
for _,elm2 in enumerate(mylist[:k] + mylist[k + 1:]):
if frozenset(elm).issubset(elm2):
break
else:
out.append(elm)
print(out)
out list will give us unique elements of the list mylist.
[[(1, 1), (1, 2), (1, 3)], [(1, 1), (1, 2), (1, 4)]]
In the above segment of code, we loop over the list and take the current index. Then we loop again over the same list but we remove the element at the current index of the first loop. Then we convert the first element of the index of the first loop into a frozenset and use the method issubset in order to check if the first element if a subset of the second element or not.
Now we just compare our dictionary d values with out list. And if, d values are not in out list we delete that key from the dictionary d. This is accomplished as follows:
for key in list(d):
if d[key] not in out:
del d[key]
print(d)
Th output dictionary d will be:
{(0, 3): [(1, 1), (1, 2), (1, 3)], (0, 4): [(1, 1), (1, 2), (1, 4)]}
I currently have the dictionary:
matrix = {(0, 0): 1, (1, 1): 1, (2, 2): 1}
And I need to create a single string that displays:
(0,0,1),(1,1,1),(2,2,1)
How can I join the dictionary keys (tuples) and value together into one string?
I was thinking of putting the keys into a list and adding the key into the list, but I am not entirely sure how to add it in the right order given that tuples are immutable.
result = []
for i, j in matrix.items():
result.append(i)
for i in result:
The basic operation you're looking for is:
[k + (v,) for k, v in matrix.items()]
To print that in your specific way, you probably want:
print(', '.join(str(k + (v,)) for k, v in matrix.items()))
Note that dictionaries are unordered, so the order of the result is undefined.
Your approach will keep them in the right order. The only thing it looks like you need to change in your code is splitting the tuple into its sub-parts:
>>> result = []
>>> for (x, y), z in matrix.items():
result.append((x, y, z))
>>> print result
[(0, 0, 1), (1, 1, 1), (2, 2, 1)]
I don't know whether this is the most pythonic solution but try this:
str(tuple(_ + (matrix[_],) for _ in matrix))
Or use %s:
print(','.join(["(%s,%s,%s)"%(*k,v) for k,v in matrix.items()]))
Or:
print(','.join([str((*k,v)) for k,v in matrix.items()]))
Or if version not above python 3.5:
print(','.join(["(%s,%s,%s)"%k+(v,) for k,v in matrix.items()]))
Or:
print(','.join([str(k+(v,)) for k,v in matrix.items()]))
Building off your work so far:
lst = []
for i,j in matrix.items():
lst.append((i[0],i[1],j))
result = ",".join( repr(e) for e in lst )
Please note that your keys are tuples which are immutable so cannot be modified, so you need to unpack them first and then join with the dictionary value.
You can use,
matrix = {(0, 0): 1, (1, 1): 1, (2, 2): 1}
# *k unpack keys
print(','.join("({},{},{})".format(*k,v) for k,v in matrix.items()))
# output,
# (0,0,1),(1,1,1),(2,2,1)
Should I remove item at the index and add item at the index?
Where should I look at to find the source for OrderedDict class?
From the Python documentation:
If a new entry overwrites an existing entry, the original insertion position is left unchanged. Deleting an entry and reinserting it will move it to the end.
The OrderedDict uses the position of a value if it is already present; if it isn't, just treats it as a new value and adds it at the end.
This is in the documentation. If you need to replace and maintain order, you'll have to do it manually:
od = OrderedDict({i:i for i in range(4)})
# od = OrderedDict([(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)])
# Replace the key and value for key == 0:
d = OrderedDict(('replace','key') if key == 0 else (key, value) for key, value in od.items())
# d = OrderedDict([('replace', 'key'), (1, 1), (2, 2), (3, 3), (4, 4)])
# Single value replaces are done easily:
d[1] = 20 # and so on..
Additionally, at the top of the documentation page you'll see a reference to the file containing, among others, the source for the OrderedDict class. It is in collections.py and, actually, the first class defined.
I'm sorry if this has been asked before, but I searched around and can't seem to figure out the syntax for doing this.
I have a dictionary and I'm trying to add all the keys that have a specific value (xColor) to my Python list (list). I know that values() and keys() don't take any arguments, but I don't know how to iterate through the elements in my dict (tile) to do what I need.
Here is my attempt:
for colors in tile.values():
for cords in tile.keys():
if tile.values(colors) == xColor:
list.append(tile.keys(cords))
else:
return
And just for reference,
xColor = 'pink'
tile = {(0,0): 'pink', ...}
tile.keys() = [(0,0), ...]
tile.values() = ['pink',...]
First, you really should read Data Structures in the tutorial, because it explains things like "how to iterate through the elements of my dict".
But briefly, you can iterate through the keys just by using the dict itself as an iterator, and you can iterate through the key-value pairs by using the items() or iteritems() methods.
Your code is iterating through the values, and then, for each one, iterating through the keys. There's no reason for that. You want the keys that go with certain values; you don't care about any other keys. Also, your function is going to return (meaning it stops both loops, and returns a useless None after all that work you did building up a list) as soon as you get a failed match.
You can fix your code in one of two ways:
matches = []
for cord, color in tile.iteritems():
if color == xColor:
matches.append(cord)
return matches
Or:
matches = []
for cord in tile:
color = tile[cord]
if color == xColor:
matches.append(cord)
return matches
The two are basically equivalent. Looking up tile[cord] to get color is simple, and very cheap.
If you know anything about list comprehensions, you may recognize the pattern in the first one as exactly what a list comprehension does. So you can convert the whole thing it to a one-liner:
return [cord for cord, color in tile.iteritems() if color == xColor]
You could use list.extend method with generator, extracting required keys:
In [9]: d = {(0, 0): 'pink', (0, 1): 'pink', (2, 3): 'blue', (3, 2): 'red'}
In [10]: x_color = 'pink'
In [11]: [k for (k, v) in d.iteritems() if v == x_color]
Out[11]: [(0, 1), (0, 0)]
In [12]: l = [(2, 4)]
In [13]: l.extend(k for (k, v) in d.iteritems() if v == x_color)
In [14]: l
Out[14]: [(2, 4), (0, 1), (0, 0)]
I have a dictionary:
test = {}
test[(1,2)] = 1
test[(4,3)] = 1
test[(1,4)] = 1
How to sort by "pseudo compound key": first element of tuple and after second element of tuple ?
test = {}
test[(1,2)] = 1
test[(4,3)] = 2
test[(1,4)] = 3
print sorted(test.iteritems())
Will give you:
[((1, 2), 1), ((1, 4), 3), ((4, 3), 2)]
If you want them back as a dictionary:
import OrderedDict
sorted_test = OrderedDict(sorted(test.iteritems()))
You've got a dictionary sorted by it's keys.
This all works because by default, tuples sort as you described.
Dictionaries cannot be sorted by definition. What you can do is get the list of keys, sort it, and then refer to the dictionary in given order. For example:
test = {}
test[(1,2)] = 1
test[(4,3)] = 2
test[(1,4)] = 3
keys = sorted(test.keys()) # nothing fancy, default sort
for key in keys:
print test[key]
>>> 1
>>> 3
>>> 2
It depends on exactly what you want. If you want the keys of test sorted in that order, all you need is
sorted(test)
If you want the values of the sorted keys, then do
[test[key] for key in sorted(test)]