Reputation: 1369
I have a list of unique keys and I want to find the unique character set used to compose those keys
idx_keys = [
"1996/a/50/18_supp__323:5",
"1996/a/50/18_supp__326:1",
"1996/a/50/18_supp__368:2",
"1996/a/50/18_supp__907:1",
"1996/a/c_2/51/sr_37_164:1",
]
I can do this
chars = set()
for k in idx_keys:
chars = chars.union(k)
print(chars)
print(f"{'-' in chars = }") # -> False
print(f"{'_' in chars = }") # -> True
But I can't do this
print({set(k) for chars in idx_keys}) # -> TypeError: unhashable type: 'set'
Can someone explain how I can do this more neatly. Obviously the logic here applies to getting the union of any nested iterable, not just a list of strings.
Caveat: I know doing this inside a set comprehension may not be ideal from a readability perspective, but humor me. I think I saw something similar with the walrus operator and would like to see what a compact solution looks like, also because it might be faster.
Upvotes: 0
Views: 111
Reputation: 11396
Or fixing your solutions and then chaining
result:
idx_keys = [
"1996/a/50/18_supp__323:5",
"1996/a/50/18_supp__326:1",
"1996/a/50/18_supp__368:2",
"1996/a/50/18_supp__907:1",
"1996/a/c_2/51/sr_37_164:1",
]
print(set(itertools.chain(*{frozenset(chars) for chars in idx_keys})))
Output:
{'7', '8', '1', 'p', '_', ':', 'c', '5', '3', 'a', '0', 's', '2', 'r', '4', '9', 'u', '/', '6'}
Upvotes: 0
Reputation: 36339
You can use functools.reduce
and operator.or_
to achieve a similar result:
from functools import reduce
import operator as op
chars = reduce(op.or_, map(set, idx_keys))
Upvotes: 1
Reputation: 11528
For that to work, you would need two nested loops like:
idx_keys = [
"1996/a/50/18_supp__323:5",
"1996/a/50/18_supp__326:1",
"1996/a/50/18_supp__368:2",
"1996/a/50/18_supp__907:1",
"1996/a/c_2/51/sr_37_164:1",
]
print({char for key in idx_keys for char in key})
As for the error, set()
can only contain non-mutable items and set()
is mutable (as opposed to frozenset()
).
Upvotes: 1