Suppose I have a list of tuples like this (without duplicates of any number):
lst = [(4, 1), (3, 8), (2, 9), (5, 6), (7, 0)]
I know an element value a
and I want to find the paired value b
.
However, I do not know if a
is the first or the second element of the tuple.
Is there a way to find it easily and cleanly?
I tried this:
a = 8
pair = next(t for t in lst if t[0] == a or t[1] == a)
b = pair[0] if pair[1] == a else pair[1]
This does not look good... Does something smarter exist?
There exists a really cool trick for bi-directional maps in O(n). First you must flatten your list:
l = [1, 4, 3, 8, 9, 2, 5, 6, 7, 0]
Then finding the associated element of one is really simple:
a = 8
b = l[l.index(a) ^ 1]
This works because xor'ing a number with 1 adds one if the number is even, and subtracts one if it is odd.
Use list comprehension.
>>> lst = [(1, 4), (3, 8), (9, 2), (5, 6), (7, 0)]
>>> next(y if 8 == x else x for x,y in lst if 8 in (x,y))
3
>>> next(x[1] if 8 == x[0] else x[0] for x in lst if 8 in x)
3
What about:
>>> lst = [(1, 4), (3, 8), (9, 2), (5, 6), (7, 0)]
>>> a = 8
>>> next([i[i.index(a) ^ 1] for i in lst if a in i])
3
>>> a = 4
>>> next(i[i.index(a) ^ 1] for i in lst if a in i)
1
>>> a = 7
>>> next(i[i.index(a) ^ 1] for i in lst if a in i)
0
If your lst
is not changed, and you're performing multiple lookups, you can build a lookup table in linear time ( O(n)
) to get answer in constant time ( O(1)
) or close to it in average case.
If your lst
contains consecutive integers, and one of them is 0
, you can use list as lookup table to get O(1)
lookup:
lookup = [None] * len(lst) * 2
for x, y in lst:
lookup[x] = y
lookup[y] = x
print(lookup[4]) # 1
If not, you can use dict
instead (slower lookup, more possibilities). You can easily switch to it at any time, because it can be built similar to the list above:
lookup = {}
for x, y in lst:
lookup[x] = y
lookup[y] = x
It can also be built in functional way:
from itertools import chain
flatten = chain.from_iterable
dct = dict(flatten(((x, y), (y, x)) for x, y in lst))
You can do it in this way
lst = [(4, 1), (3, 8), (2, 9), (5, 6), (7, 0)]
#number to be searched
num = 3
x = list(filter(lambda y: num in y, lst))
if x:
x = list(x[0])
x.remove(num)
print(x)
else:
print('Not Found')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.