I have a list of lists, and will do a search on it which will yield just one result. The following code works but isn't intuitive because it doesn't really express the intent of what I'm trying to do... it looks like I'm trying to return a list, and just happen to want to return the first item in the last: which isn't true, as I always will want just one item, never a list. Anything more intuitive here?
game = [g for g in games if g.num==5 and re.search("ucla", g.a_name, re.I)][0]
Sadly, there isn't a built-in method in Python for searching in a list using a helper function.
However, you can use a generator expression and make it stop on first match instead on iterating over the remaining list even if a match is already found.
game = next(g for g in games if g.num==5 and re.search("ucla", g.a_name, re.I))
Or maybe more functional approach (this is not equivalent to the previous one on Python 2.x, because it generates the whole list, and doesn't stop at the first matching element. On Python 3.x filter returns an iterator and behavior is same).
game = next(filter(lambda g: g.num==5 and re.search("ucla", g.a_name, re.I), games))
It's a matter of preference whether the filter is clearer or not. BDFL prefers comprehension tho.
list_games = [g for g in games if g.num==5 and re.search("ucla", g.a_name, re.I)]
game = list_games[0]
You can explicitly assign the first element of that list to your variable game. That makes it a bit clearer.
Related
I'm trying to run this block of code.
castResultType = list(filterResultSet[1:32:5])
cleanList = []
for i in castResultType:
cleanList.append(re.sub('[^\d\.]', '',castResultType[i]))
print(cleanList)
I'm hoping to get essentially each item in the list castResultType, which is getting specific values from the list filterResultSet inserted into the empty list cleanList. While also having the regex above applied to each value from castResultType before it's inserted into cleanList. I'm sure I'm doing something wrong, and would appreciate any assistance. I'm also very new to python and programming in general, so I apologize if I'm asking something stupid.
The problem you're (probably) facing is in this line: for i in castResultType.
What this line is doing is looping over the values within our (list) castResultType and assigning its elements to i. However, when you call castResultType[i], you're asking for a non-existent index of the list.
What you probably meant to do is:
for i in range(len(castResultType)):
cleanList.append(re.sub('[^\d\.]', '',castResultType[i]))
# etc
What you could also do is:
for i in castResultType:
cleanList.append(re.sub('[^\d\.]', '', i))
# etc
There are a lot of other ways of coding what you want to do, but these are probably the most familiar for a beginner.
In addition to the bug in your looping, the problem could be in your use of regular expressions. I recommend experimenting with your regular expression on a single element from castResultType before looping through.
You can use the built-in map function to map a function to items in an iterable:
clean_list = list(map(lambda elem: re.sub('[^\d\.]', '', elem), castResultType))
I have a creative problem that I want to solve.
Let's say if I have two list as below. I want to compare if all elements in the req_param list are also in the full_list. I know it is easy to do the same using a for loop and getting the answer. But I am trying to figure out if there is a python3 in-built fxn to do the same..
req_param = ['ele1','ele2','ele3','ele4]
full_param = [['ele1','ele2','ele3','ele4','ele6']
During the comparison, I don't care if there are additional elements in full_param list. I just care that if full_param has all the elements of the req_param, then somehow I want to return it true else, I want to return it false.
Currently, this works with the for loop. But really think there should be an inbuilt fxn like compare. The most important part is that each element may not come in the same order, so I am ok to sort my list before passing it to a fxn...
As was mentioned there are several ways:
Use all(): if all(item in full_list for item in req_param):
Use set(): if set(req_param).issubset(set(full_param)):
I figured out a different way you can solve the problem.
You could just use set() and len() to solve the problem instead of for loop
Here's how:
r = ['ele1','ele2','ele3','ele4']
f = ['ele1','ele2','ele3','ele4','ele6']
print(len(set(r)-set(f))==0)
use all keyword , it returns True if all the conditions are satisfied else it returns False
I have a function:
def fun(l):
for i in l:
if len(i)==10:
l.append('+91 {} {}'.format(i[:5],i[5:]))
l.remove(i)
if len(i)==11:
j=list(''.join(i))
j.remove(i[0])
l.append('+91 {} {}'.format(''.join(j[:5]),''.join(j[5:])))
l.remove(i)
if len(i)==12:
j=list(''.join(i))
j.remove(i[0])
j.remove(i[1])
l.append('+91 {} {}'.format(''.join(j[:5]),''.join(j[5:])))
l.remove(i)
if len(i)==13:
j=list(''.join(i))
j.remove(i[0])
j.remove(i[1])
j.remove(i[2])
l.append('+91 {} {}'.format(''.join(j[:5]),''.join(j[5:])))
l.remove(i)
return l
say l=['9195969878','07895462130','919875641230']
I am getting the output as
['+91 91959 69878','7895462130','+91 98756 41230']
But i have suppose to get the output as:
['+91 91959 69878','+91 78954 62130,'+91 98756 41230']
Actually this function is escaping all that is positioned even no in 'l' list. Kindly suggest
The first problem is that you're mutating the list while iterating over it. In this particular case, this caused the loop to skip some items, as you deleted items that were earlier. In other Python versions it might trigger an error. But you're returning your result, so I don't see why you're mutating the list at all.
Secondly your code does some roundabout things, in particular ''.join(i) which is absolutely redundant (it literally rebuilds the same string), and series of remove() calls which almost certainly don't do what you expect. If you remove the first item from [1,2,3], the list becomes [2,3], and if you follow that by removing the second item (index 1) you end up with [2]. This is the same sort of issue your for loop has with the other remove.
I would also restructure the code a bit to avoid code duplication. I get something like:
def fun(l):
return ['+91 {} {}'.format(i[-10:-5],i[-5:])
for i in l]
This never alters l, makes one single pass, and joins all the different length behaviours by observing that we're using parts at a fixed distance from the end. There is one caveat: other lengths aren't handled separately. I don't know if those occur, or how you actually want them handled (the old code would leave them as is). We can easily enough specify other behaviour:
def fun(l):
return ['+91 {} {}'.format(i[-10:-5],i[-5:]) if 10<=len(i)<=13
else i
for i in l]
This still doesn't reproduce the behaviour that reformatted numbers were appended at the end, but I'm not sure you really wanted that. It made little sense for the loop to process its own output in the first place.
You are modifying the list l as you go - I would suggest to create a new list and add things to this list. Is there a reason you want to mutate in place?
If you are intent on mutating in place, why not just do something like this?
l[index] = '+91 {} {}'.format(i[:5],i[5:])
Also, here is the first google result for "python phone number library": https://github.com/daviddrysdale/python-phonenumbers as it may be of use to you. (Never used it, am not the maintainer.)
The context of what I'm doing: I'm translating if/then/else statements between 2 languages via a Python script (2x for now, but may eventually upgrade to 3x). I have a function that takes the if/then/else statement from the original language and breaks it into a list of [if_clause,then_clause,else_clause]. The thing is, there may be (and often are) nested if statements in the then and/or else clauses. For example, I would pass a string like...
if (sim_time<=1242) then (new_tmaxF0740) else if (sim_time<=2338) then (new_tmaxF4170) else (new_tmaxF7100)
...to my function, and it would return the list...
['(sim_time<=1242)','(new_tmaxF0740)','if (sim_time<=2338) then (new_tmaxF4170) else (new_tmaxF7100)']
So, as you can see, in this case the else clause needs to be further broken up by running it again through the same function I used to generate the list, this time only passing the last list element to that function. I am going about this by testing the original string to see if there are more than 1 if statements contained (I already have the regex for this) and my thought is to use a loop to create nested lists within the original list, that might then look like...
[if_clause,then_clause,[if_clause, then_clause, else_clause]]
These can be nested any number of times/to any dimension. My plan so far is to write a loop that looks for the next nested if statement (using a regex), and reassigns the list index where the if statement is found to the resultant list from applying my if_extract() function to break up the statement.
I feel like list comprehension may not do this, because to find the indices, it seems like the list comprehension statement might have to dynamically change. Maybe better suited for map, but I'm not sure how to apply? I ultimately want to iterate through the loop to return the index of the next (however deeply nested) if statement so I can continue breaking them apart with my function.
If I understand correctly, you could call your function recursively.
def split_if_then_else(str):
if check_if_if_in_string_function(str)
if_clause, then_clause, else_clause = split_str_core_function(str)
then_clause = split_if_then_else(str)
return [if_clause, then_clause, else_clause]
else:
return str
I didn't test it since I don't know what functions you are using exactly, but I think something like this should work
I have admittedly not done a huge amount of research on this topic, but I am trying to get something done quickly. I have a dictionary with integers as keys and lists as values. Previously, I was checking for a list being in the dictionary with a simple if statement:
if(someList is in someDictionary.values()):
someCode() #failure
However, I realized it is incorrect for what I was doing, and I only want to check for the inclusion of the first value of the list in the dictionary's values, e.g
if(someList[0] == someValueInDictionary[0]):
someCode() #failure
I first tried
if(someList[0] is in someDictionary.values()[0]):
someCode() #failure
But that clearly doesn't work. As someDictionary.values() is a list in itself. I realize I could iterate through all of the values to check, e.g
for list in someDictionary.values():
if(someList[0] == list[0]):
someCode() #failure
actualCode() #success
But this really messes up the flow of my program. I am a new Python programmer, most experienced in Java, and I am trying to get the conciseness and convenience of Python in my bones, as such I thought there might be a better solution for what I am testing for. If there is not, I can make the iteration thing work, but if there is, I would greatly appreciate it!
Thanks in advance!
Use the any() function with a generator expression to find if there is any dictionary value that contains your item:
if any(someList[0] in v for v in someDictionary.itervalues()):
# item found
Use someDictionary.values() on Python 3. The generator expression loops over the dictionary values (without producing a list of all values first) and tests against each value, one by one as the generator expression is iterated over.
any() only tests elements from the generator expression until one is True, and then stops looping, making this relatively efficient.
If you need to have the key of the matching value, use next():
next((k for k, v in someDictionary.iteritems() if someList[0] in v), None)
which returns either the matching key, or None in no match is found.
Try this, assuming that you want to check the first element of someList against the first element in all of someDictionary's list values (the code in the question seems to indicate that's what you want):
if someList[0] in (x[0] for x in someDictionary.itervalues()):
someCode()
But if what you want is to check if the first element of someList is in any of the lists of values, then try this:
import itertools as it
if someList[0] in it.chain(*someDictionary.itervalues()):
someCode()