partial match dictionary key(of tuples) in python
I have a dictionary that maps 3tuple to 3tuple where key-tuples have some element in common
dict= { (a,b,c):(1,2,3),
(a,b,d):tuple1,
(a,e,b):tuple,
.
(f,g,h):tuple3,
.
.
.
tuple:tuple
}
now how can I find the values that match to (a,b,anyX) in a dictionary ie (1:2:3) and tuple1
this is computer generated and very large thus, it takes effort to determine anyX.
so, any good ways I can do this?
edit:partial matching of (f,g,*),(f, *,g) to tuple3 will also be helpful but not necessary.
python python-2.7 dictionary
add a comment |
I have a dictionary that maps 3tuple to 3tuple where key-tuples have some element in common
dict= { (a,b,c):(1,2,3),
(a,b,d):tuple1,
(a,e,b):tuple,
.
(f,g,h):tuple3,
.
.
.
tuple:tuple
}
now how can I find the values that match to (a,b,anyX) in a dictionary ie (1:2:3) and tuple1
this is computer generated and very large thus, it takes effort to determine anyX.
so, any good ways I can do this?
edit:partial matching of (f,g,*),(f, *,g) to tuple3 will also be helpful but not necessary.
python python-2.7 dictionary
2
do you also need to support get(f,*,h) returning tuple3?
– Foon
Sep 19 '13 at 11:46
not in the current version, but that would also be great
– Aavaas
Sep 19 '13 at 11:48
Notes:(1:2:3)causes aSyntaxError, and it's generally not a good idea to name variables after builtins, such astupleanddict.
– user707650
Sep 19 '13 at 12:03
sorry I meant (1,2,3) and dict and tuple was to show the idea
– Aavaas
Sep 19 '13 at 12:24
add a comment |
I have a dictionary that maps 3tuple to 3tuple where key-tuples have some element in common
dict= { (a,b,c):(1,2,3),
(a,b,d):tuple1,
(a,e,b):tuple,
.
(f,g,h):tuple3,
.
.
.
tuple:tuple
}
now how can I find the values that match to (a,b,anyX) in a dictionary ie (1:2:3) and tuple1
this is computer generated and very large thus, it takes effort to determine anyX.
so, any good ways I can do this?
edit:partial matching of (f,g,*),(f, *,g) to tuple3 will also be helpful but not necessary.
python python-2.7 dictionary
I have a dictionary that maps 3tuple to 3tuple where key-tuples have some element in common
dict= { (a,b,c):(1,2,3),
(a,b,d):tuple1,
(a,e,b):tuple,
.
(f,g,h):tuple3,
.
.
.
tuple:tuple
}
now how can I find the values that match to (a,b,anyX) in a dictionary ie (1:2:3) and tuple1
this is computer generated and very large thus, it takes effort to determine anyX.
so, any good ways I can do this?
edit:partial matching of (f,g,*),(f, *,g) to tuple3 will also be helpful but not necessary.
python python-2.7 dictionary
python python-2.7 dictionary
edited Sep 19 '13 at 12:22
Aavaas
asked Sep 19 '13 at 11:39
AavaasAavaas
347414
347414
2
do you also need to support get(f,*,h) returning tuple3?
– Foon
Sep 19 '13 at 11:46
not in the current version, but that would also be great
– Aavaas
Sep 19 '13 at 11:48
Notes:(1:2:3)causes aSyntaxError, and it's generally not a good idea to name variables after builtins, such astupleanddict.
– user707650
Sep 19 '13 at 12:03
sorry I meant (1,2,3) and dict and tuple was to show the idea
– Aavaas
Sep 19 '13 at 12:24
add a comment |
2
do you also need to support get(f,*,h) returning tuple3?
– Foon
Sep 19 '13 at 11:46
not in the current version, but that would also be great
– Aavaas
Sep 19 '13 at 11:48
Notes:(1:2:3)causes aSyntaxError, and it's generally not a good idea to name variables after builtins, such astupleanddict.
– user707650
Sep 19 '13 at 12:03
sorry I meant (1,2,3) and dict and tuple was to show the idea
– Aavaas
Sep 19 '13 at 12:24
2
2
do you also need to support get(f,*,h) returning tuple3?
– Foon
Sep 19 '13 at 11:46
do you also need to support get(f,*,h) returning tuple3?
– Foon
Sep 19 '13 at 11:46
not in the current version, but that would also be great
– Aavaas
Sep 19 '13 at 11:48
not in the current version, but that would also be great
– Aavaas
Sep 19 '13 at 11:48
Notes:
(1:2:3) causes a SyntaxError, and it's generally not a good idea to name variables after builtins, such as tuple and dict.– user707650
Sep 19 '13 at 12:03
Notes:
(1:2:3) causes a SyntaxError, and it's generally not a good idea to name variables after builtins, such as tuple and dict.– user707650
Sep 19 '13 at 12:03
sorry I meant (1,2,3) and dict and tuple was to show the idea
– Aavaas
Sep 19 '13 at 12:24
sorry I meant (1,2,3) and dict and tuple was to show the idea
– Aavaas
Sep 19 '13 at 12:24
add a comment |
4 Answers
4
active
oldest
votes
Lets say if you're passing None for the missing keys then you can use all and zip:
>>> from itertools import permutations
>>> import random
#create a sample dict
>>> dic = {k:random.randint(1, 1000) for k in permutations('abcde', 3)}
def partial_match(key, d):
for k, v in d.iteritems():
if all(k1 == k2 or k2 is None for k1, k2 in zip(k, key)):
yield v
...
>>> list(partial_match(('a', 'b', None), dic))
[541, 470, 734]
>>> list(partial_match(('a', None, 'b'), dic))
[460, 966, 45]
#Answer check
>>> [dic[('a', 'b', x)] for x in 'cde']
[541, 734, 470]
>>> [dic[('a', x, 'b')] for x in 'cde']
[966, 460, 45]
if all(k1 == k2 or k2 is None for k1, k2 in zip(k, key)): yield v "wow this is some mind bending line"
– Aavaas
Sep 19 '13 at 12:14
@TheAvsall()will return True if all items satisfied the conditionk1 == k2 or k2 is None, andzip()returns items on the same index from both iterables.yieldis used to make a generator function.
– Ashwini Chaudhary
Sep 19 '13 at 12:32
so this is more simple then, thank you!
– Aavaas
Sep 19 '13 at 12:52
In Python 3.x , .iteritems() is replaced with .items()
– lacrima
7 hours ago
add a comment |
You could reconstruct your dictionary into a triply nested dict.
dict= { ("foo", 4 , "q"): 9,
("foo", 4 , "r"): 8,
("foo", 8 , "s"): 7,
("bar", 15, "t"): 6,
("bar", 16, "u"): 5,
("baz", 23, "v"): 4
}
d = {}
for (a,b,c), value in dict.iteritems():
if a not in d:
d[a] = {}
if b not in d[a]:
d[a][b] = {}
d[a][b][c] = value
Here, d is equivalent to:
d = {
"foo": {
4:{
"q": 9,
"r": 8
},
8:{
"s": 7
}
},
"bar":{
15:{
"t": 6
}
16:{
"u": 5
}
},
"baz":{
23{
"v": 4
}
}
}
Now you can easily iterate through the possible third keys, given the first and second.
#find all keys whose first two elements are "foo" and 4
a = "foo"
b = 4
for c in d[a][b].iterkeys():
print c
Result:
q
r
This only works for matching the third key. For instance, you wouldn't be able to find all second keys, given the third and the first.
This is the only one so far with sublinear lookup times. +1 and this data structure can be used to look in any position, with an accessor function.
– Jacob
Sep 19 '13 at 12:37
add a comment |
There might be other ways, but assuming you just need to do a single search (in other words there might be ways to build better data structures for repeated searching):
(Note that this handles arbitrary lengthed tuple's with the '*' in multiple possible locations)
def match(tup,target):
if len(tup) != len(target):
return False
for i in xrange(len(tup)):
if target[i] != "*" and tup[i] != target[i]:
return False
return True
def get_tuples(mydict,target):
keys = filter(lambda x: match(x,target),mydict.keys())
return [mydict[key] for key in keys]
#example:
dict= { (1,3,5):(1,2,3),
(1,3,6):(1,5,7),
(1,2,5):(1,4,5),
}
print get_tuples(dict,(1,3,'*'))
.
This correctly answers the question, but with O(n). The point of a dict is to get O(1) lookup. Just a heads up the wildcard search will be slow compared to a lookup. If convenient for the rest of your code use a better data structure for wildcard search.
– Jacob
Sep 19 '13 at 12:51
I have timed your function and it performs constantly slower than the implementation by @hcwhsa by about 0.012 seconds for a dictionary of about 10,000 elements. And thank you very much for quick answer.
– Aavaas
Sep 19 '13 at 12:56
add a comment |
@AshwiniChaudhary's solution can be trivially adapted for an object-oriented solution. You can subclass dict and add a method:
class tup_dict(dict):
def getitems_fromtup(self, key):
for k, v in self.items():
if all(k1 == k2 or k2 is None for k1, k2 in zip(k, key)):
yield v
d = tup_dict({("foo", 4 , "q"): 9,
("foo", 4 , "r"): 8,
("foo", 8 , "s"): 7,
("bar", 15, "t"): 6,
("bar", 16, "u"): 5,
("baz", 23, "v"): 4})
res = list(d.getitems_fromtup(("foo", 4, None))) # [9, 8]
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f18893624%2fpartial-match-dictionary-keyof-tuples-in-python%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
Lets say if you're passing None for the missing keys then you can use all and zip:
>>> from itertools import permutations
>>> import random
#create a sample dict
>>> dic = {k:random.randint(1, 1000) for k in permutations('abcde', 3)}
def partial_match(key, d):
for k, v in d.iteritems():
if all(k1 == k2 or k2 is None for k1, k2 in zip(k, key)):
yield v
...
>>> list(partial_match(('a', 'b', None), dic))
[541, 470, 734]
>>> list(partial_match(('a', None, 'b'), dic))
[460, 966, 45]
#Answer check
>>> [dic[('a', 'b', x)] for x in 'cde']
[541, 734, 470]
>>> [dic[('a', x, 'b')] for x in 'cde']
[966, 460, 45]
if all(k1 == k2 or k2 is None for k1, k2 in zip(k, key)): yield v "wow this is some mind bending line"
– Aavaas
Sep 19 '13 at 12:14
@TheAvsall()will return True if all items satisfied the conditionk1 == k2 or k2 is None, andzip()returns items on the same index from both iterables.yieldis used to make a generator function.
– Ashwini Chaudhary
Sep 19 '13 at 12:32
so this is more simple then, thank you!
– Aavaas
Sep 19 '13 at 12:52
In Python 3.x , .iteritems() is replaced with .items()
– lacrima
7 hours ago
add a comment |
Lets say if you're passing None for the missing keys then you can use all and zip:
>>> from itertools import permutations
>>> import random
#create a sample dict
>>> dic = {k:random.randint(1, 1000) for k in permutations('abcde', 3)}
def partial_match(key, d):
for k, v in d.iteritems():
if all(k1 == k2 or k2 is None for k1, k2 in zip(k, key)):
yield v
...
>>> list(partial_match(('a', 'b', None), dic))
[541, 470, 734]
>>> list(partial_match(('a', None, 'b'), dic))
[460, 966, 45]
#Answer check
>>> [dic[('a', 'b', x)] for x in 'cde']
[541, 734, 470]
>>> [dic[('a', x, 'b')] for x in 'cde']
[966, 460, 45]
if all(k1 == k2 or k2 is None for k1, k2 in zip(k, key)): yield v "wow this is some mind bending line"
– Aavaas
Sep 19 '13 at 12:14
@TheAvsall()will return True if all items satisfied the conditionk1 == k2 or k2 is None, andzip()returns items on the same index from both iterables.yieldis used to make a generator function.
– Ashwini Chaudhary
Sep 19 '13 at 12:32
so this is more simple then, thank you!
– Aavaas
Sep 19 '13 at 12:52
In Python 3.x , .iteritems() is replaced with .items()
– lacrima
7 hours ago
add a comment |
Lets say if you're passing None for the missing keys then you can use all and zip:
>>> from itertools import permutations
>>> import random
#create a sample dict
>>> dic = {k:random.randint(1, 1000) for k in permutations('abcde', 3)}
def partial_match(key, d):
for k, v in d.iteritems():
if all(k1 == k2 or k2 is None for k1, k2 in zip(k, key)):
yield v
...
>>> list(partial_match(('a', 'b', None), dic))
[541, 470, 734]
>>> list(partial_match(('a', None, 'b'), dic))
[460, 966, 45]
#Answer check
>>> [dic[('a', 'b', x)] for x in 'cde']
[541, 734, 470]
>>> [dic[('a', x, 'b')] for x in 'cde']
[966, 460, 45]
Lets say if you're passing None for the missing keys then you can use all and zip:
>>> from itertools import permutations
>>> import random
#create a sample dict
>>> dic = {k:random.randint(1, 1000) for k in permutations('abcde', 3)}
def partial_match(key, d):
for k, v in d.iteritems():
if all(k1 == k2 or k2 is None for k1, k2 in zip(k, key)):
yield v
...
>>> list(partial_match(('a', 'b', None), dic))
[541, 470, 734]
>>> list(partial_match(('a', None, 'b'), dic))
[460, 966, 45]
#Answer check
>>> [dic[('a', 'b', x)] for x in 'cde']
[541, 734, 470]
>>> [dic[('a', x, 'b')] for x in 'cde']
[966, 460, 45]
edited Sep 19 '13 at 12:18
answered Sep 19 '13 at 12:01
Ashwini ChaudharyAshwini Chaudhary
179k35325391
179k35325391
if all(k1 == k2 or k2 is None for k1, k2 in zip(k, key)): yield v "wow this is some mind bending line"
– Aavaas
Sep 19 '13 at 12:14
@TheAvsall()will return True if all items satisfied the conditionk1 == k2 or k2 is None, andzip()returns items on the same index from both iterables.yieldis used to make a generator function.
– Ashwini Chaudhary
Sep 19 '13 at 12:32
so this is more simple then, thank you!
– Aavaas
Sep 19 '13 at 12:52
In Python 3.x , .iteritems() is replaced with .items()
– lacrima
7 hours ago
add a comment |
if all(k1 == k2 or k2 is None for k1, k2 in zip(k, key)): yield v "wow this is some mind bending line"
– Aavaas
Sep 19 '13 at 12:14
@TheAvsall()will return True if all items satisfied the conditionk1 == k2 or k2 is None, andzip()returns items on the same index from both iterables.yieldis used to make a generator function.
– Ashwini Chaudhary
Sep 19 '13 at 12:32
so this is more simple then, thank you!
– Aavaas
Sep 19 '13 at 12:52
In Python 3.x , .iteritems() is replaced with .items()
– lacrima
7 hours ago
if all(k1 == k2 or k2 is None for k1, k2 in zip(k, key)): yield v "wow this is some mind bending line"
– Aavaas
Sep 19 '13 at 12:14
if all(k1 == k2 or k2 is None for k1, k2 in zip(k, key)): yield v "wow this is some mind bending line"
– Aavaas
Sep 19 '13 at 12:14
@TheAvs
all() will return True if all items satisfied the condition k1 == k2 or k2 is None, and zip() returns items on the same index from both iterables. yield is used to make a generator function.– Ashwini Chaudhary
Sep 19 '13 at 12:32
@TheAvs
all() will return True if all items satisfied the condition k1 == k2 or k2 is None, and zip() returns items on the same index from both iterables. yield is used to make a generator function.– Ashwini Chaudhary
Sep 19 '13 at 12:32
so this is more simple then, thank you!
– Aavaas
Sep 19 '13 at 12:52
so this is more simple then, thank you!
– Aavaas
Sep 19 '13 at 12:52
In Python 3.x , .iteritems() is replaced with .items()
– lacrima
7 hours ago
In Python 3.x , .iteritems() is replaced with .items()
– lacrima
7 hours ago
add a comment |
You could reconstruct your dictionary into a triply nested dict.
dict= { ("foo", 4 , "q"): 9,
("foo", 4 , "r"): 8,
("foo", 8 , "s"): 7,
("bar", 15, "t"): 6,
("bar", 16, "u"): 5,
("baz", 23, "v"): 4
}
d = {}
for (a,b,c), value in dict.iteritems():
if a not in d:
d[a] = {}
if b not in d[a]:
d[a][b] = {}
d[a][b][c] = value
Here, d is equivalent to:
d = {
"foo": {
4:{
"q": 9,
"r": 8
},
8:{
"s": 7
}
},
"bar":{
15:{
"t": 6
}
16:{
"u": 5
}
},
"baz":{
23{
"v": 4
}
}
}
Now you can easily iterate through the possible third keys, given the first and second.
#find all keys whose first two elements are "foo" and 4
a = "foo"
b = 4
for c in d[a][b].iterkeys():
print c
Result:
q
r
This only works for matching the third key. For instance, you wouldn't be able to find all second keys, given the third and the first.
This is the only one so far with sublinear lookup times. +1 and this data structure can be used to look in any position, with an accessor function.
– Jacob
Sep 19 '13 at 12:37
add a comment |
You could reconstruct your dictionary into a triply nested dict.
dict= { ("foo", 4 , "q"): 9,
("foo", 4 , "r"): 8,
("foo", 8 , "s"): 7,
("bar", 15, "t"): 6,
("bar", 16, "u"): 5,
("baz", 23, "v"): 4
}
d = {}
for (a,b,c), value in dict.iteritems():
if a not in d:
d[a] = {}
if b not in d[a]:
d[a][b] = {}
d[a][b][c] = value
Here, d is equivalent to:
d = {
"foo": {
4:{
"q": 9,
"r": 8
},
8:{
"s": 7
}
},
"bar":{
15:{
"t": 6
}
16:{
"u": 5
}
},
"baz":{
23{
"v": 4
}
}
}
Now you can easily iterate through the possible third keys, given the first and second.
#find all keys whose first two elements are "foo" and 4
a = "foo"
b = 4
for c in d[a][b].iterkeys():
print c
Result:
q
r
This only works for matching the third key. For instance, you wouldn't be able to find all second keys, given the third and the first.
This is the only one so far with sublinear lookup times. +1 and this data structure can be used to look in any position, with an accessor function.
– Jacob
Sep 19 '13 at 12:37
add a comment |
You could reconstruct your dictionary into a triply nested dict.
dict= { ("foo", 4 , "q"): 9,
("foo", 4 , "r"): 8,
("foo", 8 , "s"): 7,
("bar", 15, "t"): 6,
("bar", 16, "u"): 5,
("baz", 23, "v"): 4
}
d = {}
for (a,b,c), value in dict.iteritems():
if a not in d:
d[a] = {}
if b not in d[a]:
d[a][b] = {}
d[a][b][c] = value
Here, d is equivalent to:
d = {
"foo": {
4:{
"q": 9,
"r": 8
},
8:{
"s": 7
}
},
"bar":{
15:{
"t": 6
}
16:{
"u": 5
}
},
"baz":{
23{
"v": 4
}
}
}
Now you can easily iterate through the possible third keys, given the first and second.
#find all keys whose first two elements are "foo" and 4
a = "foo"
b = 4
for c in d[a][b].iterkeys():
print c
Result:
q
r
This only works for matching the third key. For instance, you wouldn't be able to find all second keys, given the third and the first.
You could reconstruct your dictionary into a triply nested dict.
dict= { ("foo", 4 , "q"): 9,
("foo", 4 , "r"): 8,
("foo", 8 , "s"): 7,
("bar", 15, "t"): 6,
("bar", 16, "u"): 5,
("baz", 23, "v"): 4
}
d = {}
for (a,b,c), value in dict.iteritems():
if a not in d:
d[a] = {}
if b not in d[a]:
d[a][b] = {}
d[a][b][c] = value
Here, d is equivalent to:
d = {
"foo": {
4:{
"q": 9,
"r": 8
},
8:{
"s": 7
}
},
"bar":{
15:{
"t": 6
}
16:{
"u": 5
}
},
"baz":{
23{
"v": 4
}
}
}
Now you can easily iterate through the possible third keys, given the first and second.
#find all keys whose first two elements are "foo" and 4
a = "foo"
b = 4
for c in d[a][b].iterkeys():
print c
Result:
q
r
This only works for matching the third key. For instance, you wouldn't be able to find all second keys, given the third and the first.
answered Sep 19 '13 at 12:08
KevinKevin
59.6k1169114
59.6k1169114
This is the only one so far with sublinear lookup times. +1 and this data structure can be used to look in any position, with an accessor function.
– Jacob
Sep 19 '13 at 12:37
add a comment |
This is the only one so far with sublinear lookup times. +1 and this data structure can be used to look in any position, with an accessor function.
– Jacob
Sep 19 '13 at 12:37
This is the only one so far with sublinear lookup times. +1 and this data structure can be used to look in any position, with an accessor function.
– Jacob
Sep 19 '13 at 12:37
This is the only one so far with sublinear lookup times. +1 and this data structure can be used to look in any position, with an accessor function.
– Jacob
Sep 19 '13 at 12:37
add a comment |
There might be other ways, but assuming you just need to do a single search (in other words there might be ways to build better data structures for repeated searching):
(Note that this handles arbitrary lengthed tuple's with the '*' in multiple possible locations)
def match(tup,target):
if len(tup) != len(target):
return False
for i in xrange(len(tup)):
if target[i] != "*" and tup[i] != target[i]:
return False
return True
def get_tuples(mydict,target):
keys = filter(lambda x: match(x,target),mydict.keys())
return [mydict[key] for key in keys]
#example:
dict= { (1,3,5):(1,2,3),
(1,3,6):(1,5,7),
(1,2,5):(1,4,5),
}
print get_tuples(dict,(1,3,'*'))
.
This correctly answers the question, but with O(n). The point of a dict is to get O(1) lookup. Just a heads up the wildcard search will be slow compared to a lookup. If convenient for the rest of your code use a better data structure for wildcard search.
– Jacob
Sep 19 '13 at 12:51
I have timed your function and it performs constantly slower than the implementation by @hcwhsa by about 0.012 seconds for a dictionary of about 10,000 elements. And thank you very much for quick answer.
– Aavaas
Sep 19 '13 at 12:56
add a comment |
There might be other ways, but assuming you just need to do a single search (in other words there might be ways to build better data structures for repeated searching):
(Note that this handles arbitrary lengthed tuple's with the '*' in multiple possible locations)
def match(tup,target):
if len(tup) != len(target):
return False
for i in xrange(len(tup)):
if target[i] != "*" and tup[i] != target[i]:
return False
return True
def get_tuples(mydict,target):
keys = filter(lambda x: match(x,target),mydict.keys())
return [mydict[key] for key in keys]
#example:
dict= { (1,3,5):(1,2,3),
(1,3,6):(1,5,7),
(1,2,5):(1,4,5),
}
print get_tuples(dict,(1,3,'*'))
.
This correctly answers the question, but with O(n). The point of a dict is to get O(1) lookup. Just a heads up the wildcard search will be slow compared to a lookup. If convenient for the rest of your code use a better data structure for wildcard search.
– Jacob
Sep 19 '13 at 12:51
I have timed your function and it performs constantly slower than the implementation by @hcwhsa by about 0.012 seconds for a dictionary of about 10,000 elements. And thank you very much for quick answer.
– Aavaas
Sep 19 '13 at 12:56
add a comment |
There might be other ways, but assuming you just need to do a single search (in other words there might be ways to build better data structures for repeated searching):
(Note that this handles arbitrary lengthed tuple's with the '*' in multiple possible locations)
def match(tup,target):
if len(tup) != len(target):
return False
for i in xrange(len(tup)):
if target[i] != "*" and tup[i] != target[i]:
return False
return True
def get_tuples(mydict,target):
keys = filter(lambda x: match(x,target),mydict.keys())
return [mydict[key] for key in keys]
#example:
dict= { (1,3,5):(1,2,3),
(1,3,6):(1,5,7),
(1,2,5):(1,4,5),
}
print get_tuples(dict,(1,3,'*'))
.
There might be other ways, but assuming you just need to do a single search (in other words there might be ways to build better data structures for repeated searching):
(Note that this handles arbitrary lengthed tuple's with the '*' in multiple possible locations)
def match(tup,target):
if len(tup) != len(target):
return False
for i in xrange(len(tup)):
if target[i] != "*" and tup[i] != target[i]:
return False
return True
def get_tuples(mydict,target):
keys = filter(lambda x: match(x,target),mydict.keys())
return [mydict[key] for key in keys]
#example:
dict= { (1,3,5):(1,2,3),
(1,3,6):(1,5,7),
(1,2,5):(1,4,5),
}
print get_tuples(dict,(1,3,'*'))
.
answered Sep 19 '13 at 12:00
FoonFoon
4,63492736
4,63492736
This correctly answers the question, but with O(n). The point of a dict is to get O(1) lookup. Just a heads up the wildcard search will be slow compared to a lookup. If convenient for the rest of your code use a better data structure for wildcard search.
– Jacob
Sep 19 '13 at 12:51
I have timed your function and it performs constantly slower than the implementation by @hcwhsa by about 0.012 seconds for a dictionary of about 10,000 elements. And thank you very much for quick answer.
– Aavaas
Sep 19 '13 at 12:56
add a comment |
This correctly answers the question, but with O(n). The point of a dict is to get O(1) lookup. Just a heads up the wildcard search will be slow compared to a lookup. If convenient for the rest of your code use a better data structure for wildcard search.
– Jacob
Sep 19 '13 at 12:51
I have timed your function and it performs constantly slower than the implementation by @hcwhsa by about 0.012 seconds for a dictionary of about 10,000 elements. And thank you very much for quick answer.
– Aavaas
Sep 19 '13 at 12:56
This correctly answers the question, but with O(n). The point of a dict is to get O(1) lookup. Just a heads up the wildcard search will be slow compared to a lookup. If convenient for the rest of your code use a better data structure for wildcard search.
– Jacob
Sep 19 '13 at 12:51
This correctly answers the question, but with O(n). The point of a dict is to get O(1) lookup. Just a heads up the wildcard search will be slow compared to a lookup. If convenient for the rest of your code use a better data structure for wildcard search.
– Jacob
Sep 19 '13 at 12:51
I have timed your function and it performs constantly slower than the implementation by @hcwhsa by about 0.012 seconds for a dictionary of about 10,000 elements. And thank you very much for quick answer.
– Aavaas
Sep 19 '13 at 12:56
I have timed your function and it performs constantly slower than the implementation by @hcwhsa by about 0.012 seconds for a dictionary of about 10,000 elements. And thank you very much for quick answer.
– Aavaas
Sep 19 '13 at 12:56
add a comment |
@AshwiniChaudhary's solution can be trivially adapted for an object-oriented solution. You can subclass dict and add a method:
class tup_dict(dict):
def getitems_fromtup(self, key):
for k, v in self.items():
if all(k1 == k2 or k2 is None for k1, k2 in zip(k, key)):
yield v
d = tup_dict({("foo", 4 , "q"): 9,
("foo", 4 , "r"): 8,
("foo", 8 , "s"): 7,
("bar", 15, "t"): 6,
("bar", 16, "u"): 5,
("baz", 23, "v"): 4})
res = list(d.getitems_fromtup(("foo", 4, None))) # [9, 8]
add a comment |
@AshwiniChaudhary's solution can be trivially adapted for an object-oriented solution. You can subclass dict and add a method:
class tup_dict(dict):
def getitems_fromtup(self, key):
for k, v in self.items():
if all(k1 == k2 or k2 is None for k1, k2 in zip(k, key)):
yield v
d = tup_dict({("foo", 4 , "q"): 9,
("foo", 4 , "r"): 8,
("foo", 8 , "s"): 7,
("bar", 15, "t"): 6,
("bar", 16, "u"): 5,
("baz", 23, "v"): 4})
res = list(d.getitems_fromtup(("foo", 4, None))) # [9, 8]
add a comment |
@AshwiniChaudhary's solution can be trivially adapted for an object-oriented solution. You can subclass dict and add a method:
class tup_dict(dict):
def getitems_fromtup(self, key):
for k, v in self.items():
if all(k1 == k2 or k2 is None for k1, k2 in zip(k, key)):
yield v
d = tup_dict({("foo", 4 , "q"): 9,
("foo", 4 , "r"): 8,
("foo", 8 , "s"): 7,
("bar", 15, "t"): 6,
("bar", 16, "u"): 5,
("baz", 23, "v"): 4})
res = list(d.getitems_fromtup(("foo", 4, None))) # [9, 8]
@AshwiniChaudhary's solution can be trivially adapted for an object-oriented solution. You can subclass dict and add a method:
class tup_dict(dict):
def getitems_fromtup(self, key):
for k, v in self.items():
if all(k1 == k2 or k2 is None for k1, k2 in zip(k, key)):
yield v
d = tup_dict({("foo", 4 , "q"): 9,
("foo", 4 , "r"): 8,
("foo", 8 , "s"): 7,
("bar", 15, "t"): 6,
("bar", 16, "u"): 5,
("baz", 23, "v"): 4})
res = list(d.getitems_fromtup(("foo", 4, None))) # [9, 8]
answered Nov 26 '18 at 9:40
jppjpp
102k2165116
102k2165116
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f18893624%2fpartial-match-dictionary-keyof-tuples-in-python%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
do you also need to support get(f,*,h) returning tuple3?
– Foon
Sep 19 '13 at 11:46
not in the current version, but that would also be great
– Aavaas
Sep 19 '13 at 11:48
Notes:
(1:2:3)causes aSyntaxError, and it's generally not a good idea to name variables after builtins, such astupleanddict.– user707650
Sep 19 '13 at 12:03
sorry I meant (1,2,3) and dict and tuple was to show the idea
– Aavaas
Sep 19 '13 at 12:24