Another way:
>>> [i for i in range(len(a)) if a[i] > 2]
[2, 5]
In general, remember that while find is a ready-cooked function, list comprehensions are a general, and thus very powerful solution. Nothing prevents you from writing a find function in Python and use it later as you wish. I.e.:
>>> def find_indices(lst, condition):
... return [i for i, elem in enumerate(lst) if condition(elem)]
...
>>> find_indices(a, lambda e: e > 2)
[2, 5]
Note that I'm using lists here to mimic Matlab. It would be more Pythonic to use generators and iterators.
Answer from Eli Bendersky on Stack OverflowAnother way:
>>> [i for i in range(len(a)) if a[i] > 2]
[2, 5]
In general, remember that while find is a ready-cooked function, list comprehensions are a general, and thus very powerful solution. Nothing prevents you from writing a find function in Python and use it later as you wish. I.e.:
>>> def find_indices(lst, condition):
... return [i for i, elem in enumerate(lst) if condition(elem)]
...
>>> find_indices(a, lambda e: e > 2)
[2, 5]
Note that I'm using lists here to mimic Matlab. It would be more Pythonic to use generators and iterators.
In Python, you wouldn't use indexes for this at all, but just deal with the values—
[value for value in a if value > 2]. Usually dealing with indexes means you're not doing something the best way.If you do need an API similar to Matlab's, you would use numpy, a package for multidimensional arrays and numerical math in Python which is heavily inspired by Matlab. You would be using a numpy array instead of a list.
>>> import numpy >>> a = numpy.array([1, 2, 3, 1, 2, 3]) >>> a array([1, 2, 3, 1, 2, 3]) >>> numpy.where(a > 2) (array([2, 5]),) >>> a > 2 array([False, False, True, False, False, True], dtype=bool) >>> a[numpy.where(a > 2)] array([3, 3]) >>> a[a > 2] array([3, 3])
How can I find a value in a list using Python? - Ask a Question - TestMu AI Community
How to check if elements in a list meet a specific condition using the 'any' and 'all' functions
How to print specific elements from a list that meet a certain condition?
python - find first element and index matching condition in list - Stack Overflow
Suppose you have a list of numbers, and you want to check if any of the numbers are greater than a certain value, or if all of the numbers are less than a certain value.
That can be done with this simple code:
# Original list lst = [1, 2, 3, 4, 5] # Check if any number is greater than 3 has_greater_than_3 = any(x > 3 for x in lst) # Check if all numbers are less than 5 all_less_than_5 = all(x < 5 for x in lst) # Print the results print(has_greater_than_3) # True print(all_less_than_5) # False
The 'any' function returns True if at least one element meets the condition, and the 'all' function returns True if all elements meet the condition.
Something like this should work:
Copyl = [-1,-2,3,4,5,6]
list(x > 0 for x in l).index(True)
# Output: 2
To find all patters, we can use python built in functions using
Copyfrom itertools import filterfalse
f = filterfalse(lambda x: x[1] <= 0, enumerate(l))
print(list(f))
# [(2, 1), (3, 2), (4, 3)]
You could do it in a list comprehension. This is basically the same as your code but condensed into one line, and it builds a list of results that match the criteria.
The first way gets all the matches
Copymylist = [-1,-2,3,4,5,6]
results = [(i, el) for i, el in enumerate(mylist) if el > 0]
Another way would be to use a generator expression which is probably faster, and just unpack it. This gets the first one.
Copy*next((i, el) for i, el in enumerate(mylist) if el > 0))
This loops the list and checks the condition, then puts the index and element into a tuple. Doing this inside parentheses turns it into a generator, which is much faster because it hasn't actually got to hold everything in memory, it just generates the responses as you need them. Using next() you can iterate through them. As we only use next() once here it just generates the first match. Then we unpack it with *
As there are two other valid answers here I decided to use timeit module to time each of them and post the results. For clarity I also timed the OP's method. Here is what I found:
Copyimport timeit
# Method 1 Generator Expression
print(timeit.timeit('next((i, el) for i, el in enumerate([-1,-2,3,4,5,6]) if el > 0)', number=100000))
0.007089499999999999
# Method 2 Getting index of True
print(timeit.timeit('list(x > 0 for x in [-1,-2,3,4,5,6]).index(True)', number=100000))
0.008104599999999997
# Method 3 filter and lambda
print(timeit.timeit('myidx , myel = list(filter(lambda el: el[1] > 0, enumerate([-1,-2,3,4,5,6])))[0]', number=100000))
0.0155314
statement = """
for idx, el in enumerate([-1,-2,3,4,5,6]):
if el > 0:
myidx, myel = idx, el
break
"""
print(timeit.timeit(statement, number=100000))
0.04074070000000002
To answer the question in your title, you can conditionally add elements during a list comprehension using the syntax [x for y in z if y == a], where y == a is any condition you need - if the condition evaluates to True, then the element y will be added to the list, otherwise it will not.
I would just keep a dictionary of all of the owner data together:
ownerData = { "Shaft" : {
"carMake" : "Audi",
"carModel" : "A8",
"year" : "2015" },
"JamesBond" : {
"carMake" : "Aston",
"carModel" : "DB8",
"year" : "2012" },
"JeffBezos" : {
"carMake" : "Honda",
"carModel" : "Accord"
"year" : "1989"}
}
Now you can loop through and query it something like this:
for o in ownerData:
if "Audi" in o["carMake"]:
print("Owner %s drives a %s %s %s" % (o, o["year"], o["carMake"], o["carModel"]))
Should output:
"Owner Shaft drives a 2015 Audi A8"
This way you can expand your data set for owners without creating multiple lists.