This question already has answers here:
Find first sequence item that matches a criterion [duplicate]
(2 answers)
Closed 7 years ago.
Is there a built in function in Python that will return a single result given a list and a validation function?
For example I know I can do the following:
resource = list(filter(lambda x: x.uri == uri, subject.resources))[0]
The above will extract a resource from a list of resources, based on ther resource.uri field. Although this field value is uinique, so I know that I will either have 1 or 0 results. filter function will iterate the whole list. In my case its 20 elements, but I want to know if there is some other built-in way to stop the iteration on first match.
See https://docs.python.org/3/library/functions.html#next
next(iterator[, default])
Retrieve the next item from the iterator by calling its next() method. If default is given, it is returned if the iterator is exhausted, otherwise StopIteration is raised.
e.g. in your case:
resource = next(filter(lambda x: x.uri == uri, subject.resources), None)
Related
This question already has answers here:
Check if key exists and get the value at the same time in Python?
(3 answers)
Closed 3 years ago.
I would like to optimize this statement:
if 'key' in dictionary and dictionary['key']!=value:
Is there a way to check if a key exists in a dictionary and check the value at the same time?
Use the .get() dict method, which returns None if the key is not in the dictionary instead of throwing a KeyError exception:
d = {'a':0,'b':1}
if d.get('a')==0:
# you will enter this if-statement
if d.get('c')==0:
# you will not enter this if-statement and will not throw a KeyError
Python dict has a get() method. For example, if d is a dict, d.get(x, y) returns d[x] if it exists, otherwise it returns y. This means that your if statement can be replaced with if dictionary.get(key, value) != value.
This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Closed 3 years ago.
I'm solving some katas in CodeWars and in the current kata I'm trying to get how many times an element has occurred in a list that I set as a parameter, then and use it as the range of a for loop.
However, when I call the function it returns:
File "<pyshell#8>", line 3, in delete_nth
if order.count(item) > max_e:
AttributeError: 'NoneType' object has no attribute 'count'
here is my code
def delete_nth(order,max_e):
for item in order:
if order.count(item) > max_e:
for i in range(order.count(item) - max_e):
order = order.remove(item)
return order
l = [20,37,20,21]
delete_nth(l,1) #except [20,37,21]
The problem is this statement
order = order.remove(item)
You don't have to reassign list after removing an item.
And also list.remove returns None which the cause of your error.
So edit it to this:
order.remove(item)
The problem is that you are changing order even as you are iterating through it. You should not be doing it. If you want create a copy of the existing list and modify it.
remove function doesn't return anything, so, effectively None gets assigned to order.
def delete_nth(order,max_e):
for item in order:
if order.count(item) > max_e:
for i in range(order.count(item) - max_e):
order = order.remove(item) ======> order becomes None as remove returns None.
return order
This question already has an answer here:
Recursive code returns None [duplicate]
(1 answer)
Closed 6 years ago.
I want to search a Specific Value (an Integer) in a List in Python where the List could possibly have a Hierarchical Structure, So there could be a List on a Specific index (e.g [1,2,[[3,4],[5,6]] here the index 2 is a list it self and there could be a list in that again), and So on, or the index of Original List could have Integer values itself (e.g [1,2,3,[4,5]] in this case index 0 is an integer..
Eventually, I want the index of the searched value w.r.t original List , otherwise if searched value is not in the list, it should give me -1...I'm using recursion for that, but i'm not having the desired results...
Here's My Code
def search_in_list(L,c1):
index=-1
for i in range(len(L)):
if type(L[i])==list:
search_in_list(L[i],c1)
elif type(L[i])!=list:
if c1==L[i]:
index=i
return index
and here's an example List [1,2,[[3,4],[5,6]] So let's say i want to search 6, then it should give me 2 because that's the index of original list on which 6 is present, but i'm having -1 instead...
Can someone dig into my code and tell me the problem and solution...
Thanks in Advance
You can make some modifications to work correctly:
def search_in_list(l, needle):
for i, item in enumerate(l):
if type(item) == list:
# We found it, return current index
if search_in_list(item, needle) >= 0:
return i
else:
if needle == item:
return i
return -1
The main reason it didn't work was in the recursive call. When it returned that the item was found (by returning a non negative index) you didn't return the current index.
This question already has answers here:
Dictionary creation with fromkeys and mutable objects. A surprise [duplicate]
(3 answers)
Closed 8 years ago.
I have a dictionary indexed by 201 integer keys (0..200). the value for each of these keys is a list. generated with the code below:
dictionary=dict.fromkeys(range201,[])
i am getting this strange behaviour when i try to append items to the list belonging to one specific index, if i do this:
dictionary[1].append("foo")
i would expect this:
>>dictionary
{0:[], 1:["foo"],2:[],...}
but instead i end up with this:
>>dictionary
{0:["foo"], 1:["foo"],2:["foo"],...}
to clarify a bit the context in which the operation is performed, i am enumerating a list of values that can be None or float, i want to skip the None and append the float to the list corresponding to the enumerate index:
for i, value in enumerate(valuesList):
if value is None:
continue
dictionary[i].append(value)
this is behaviour is independent of which integer index i use, and i end up with the same values at all indices. I could use a list of lists and achieve the same result i think. but i wanted to understand this behaviour.
This is the normal behavior. All the entry of your dictionary where initialized with a reference to the same list. So when appending an element using one key, as all the key are pointing the same list, the modification is applied to all the entries of the dic.
Try this instead :
dictionary={}
for i in range(201):
#the loop make the list.__init__() (i.e. the []) being called 200 times
dictionary[i] = []
dictionary[1].append("foo")
print dictionary
This question already has answers here:
Only add to a dict if a condition is met
(14 answers)
Closed 4 years ago.
I have a function create_group with an optional parameter user_device=None. If a non-None value is provided for user_device, I want a dictionary targeting_spec to include the key-value pair "user_device": user_device, and if no non-None value is provided, I do not want targeting_spec to include this key-value pair.
How I do it now:
def create_group(..., user_device=None, ...):
...
targeting_spec = {
...
}
if user_device:
targeting_spec["user_device"] = user_device
...
Is this an accepted way of doing this? If not, what is? I ask because this seems like the type of thing Python would love to solve elegantly.
Your approach is fine, provided you don't need to support empty values.
Consider passing in user_device=0, for example. user_device is not None, but it is a falsey value.
If you need to support falsey values apart from None, use is not None to test:
if user_device is not None:
parameters["user_device"] = user_device