I have this simple function:
keys = ['snmt1/metadata/table1/ref_table1_20190324124365.csv', 'snmt1/metadata/table2/table2_ref_20190324124365.csv', 'snmt1/metadata/table3/table3_20190324124365.csv']
def better_func(keys):
for item in keys:
split_key = item.split("/")
filename = str(split_key[-1])
prefixes = ['strm','ref','trunc']
if any(x in filename for x in prefixes):
location = filename.find(x)
if location == 0:
print True
else:
print "another false"
else:
print False
What I need is the value of "x" so that I can return the index of it with the .find() function. This code above doesn't work because it is telling me:
NameError: global name 'x' is not defined
Which I understand but how can I access "x" like I can normally do in a for loop?
for x in my_list:
print x
Instead of
if any(x in filename for x in prefixes):
# do stuff with x
you can do:
x = next((p for p in prefixes if p in filename), None)
if x:
# do stuff with x
This creates an generator, and takes the next value from it -that is, the first value.
The second argument to None
is a sentinel value: if the iterator raises a StopIteration
, rather than passing this exception, then None
is returned, and bound to x
.
This does not look so useful here, but it really comes in a handy when you want the first element of a sequence that satisfies a condition, and a fallback operation if there is no such element:
elt = next((x for x in range(10) if x > 5), None)
if elt is not None:
print("{} satisfies the condition".format(elt))
else:
print("No such element found")
Note that generators are iterators too, so you can directly call next
on them. With an iterable like a list, a dict or anything else, you'd need to call iter
first. For instance, this is useful to take an arbitrary value from a dictionary:
value = next(iter(d.values()))