How to concatenate output data coming out from for loop/function - python

I have a data set as a list. From that list I need to find a keyword, and if found, I should be able to extract the complete information of that element.
att =['Email/xyz#gmail.com', 'CountryCode/US','CountryCode/UK', 'ID/12345']
from the above list, if I search only CountryCode, then the output should come as:
['CountryCode/US','CountryCode/UK']
Below is my code which I am trying, but it is returning only a single value.
Can some one help me with this code, to return all of the values as :
['CountryCode/US','CountryCode/UK']
def att_func(field,data):
for i, j in enumerate(data):
# print(i,j)
if field in j:
return [data[i]]
att =['Email/xyz#gmail.com', 'CountryCode/US','CountryCode/UK', 'ID/12345']
field ='CountryCode'
Cntry = att_func('CountryCode',att)
print(Cntry)

You're returning early in your for loop so you'll never get past the first position where the field exists, you can either use yield instead of return and make your function return a generator or just use a list comprehension
def att_func(field, data):
return [i for i in data if field in i]

Reason : This is because you are returning as soon as single data is getting.
Solution : Collect all data in list and the return collected data.
Try:
def att_func(field,data):
final_data = []
for i, j in enumerate(data):
# print(i,j)
if field in j:
final_data.append(data[i])
return final_data
att =['Email/xyz#gmail.com', 'CountryCode/US','CountryCode/UK', 'ID/12345']
field ='CountryCode'
Cntry = att_func('CountryCode',att)
print(Cntry)

att = ['Email/xyz#gmail.com', 'CountryCode/US','CountryCode/UK', 'ID/12345']
out = [item for item in att if "CountryCode" in item]
Done !
Your att_func should look like this:
def att_func(needle, haystack):
return [item for item in haystack if needle in item]
More on list comprehensions.

Related

How can I make my list return each element only once in a list?

So I wrote this code to return back every string in the given lst: list once. Here is my code
def make_unique(lst: list[str]):
s = []
for x in lst:
if lst.count(x) == 1:
s.append(x)
else:
return(x)
return s
When I put in the input:
print(make_unique(lst=['row','mun','row']))
The output returns
row
but I want my output to return
['row','mun']
which is basically all the strings in the list printed once.
How can I do this??
Why not you try this one line short code to remove duplicates from your list and make it unique
def make_unique(lst):
return list(dict.fromkeys(lst))
print(make_unique(['row','mun','row'])) #['row','mun']
Easy way to do this is turn the list into a set. A set only shows each item once and thats what you want.
lst=['row','mun','row']
setLst = set(lst)
for elem in setLst:
print(elem)
You can use set.
lst=['row','mun','row']
print(set(lst))

Having trouble understanding python output

Why does the second print lookup method return a blank and not the link acm.org? The first result makes sense but shouldn't the second result be similar?
# Define a procedure, lookup,
# that takes two inputs:
# - an index
# - keyword
# The procedure should return a list
# of the urls associated
# with the keyword. If the keyword
# is not in the index, the procedure
# should return an empty list.
index = [['udacity', ['http://udacity.com', 'http://npr.org']],
['computing', ['http://acm.org']]]
def lookup(index,keyword):
for p in index:
if p[0] == keyword:
return p[1]
return []
print lookup(index,'udacity')
#>>> ['http://udacity.com','http://npr.org']
print lookup(index,'computing')
Results:
['http://udacity.com', 'http://npr.org']
[]
Your indentation has a typo. You are returning [] if the first entry doesn't match. It should be:
def lookup(index,keyword):
for p in index:
if p[0] == keyword:
return p[1]
return []
I highly recommend use dictionaries for this case.
It will be like that:
index = {'udacity': ['http://udacity.com', 'http://npr.org'],
'computing': ['http://acm.org']}
def lookup(index, keyword):
return index[keyword] if keyword in index else []
This is faster and clearly. And for sure, you have more possibilities for flexible work with dict than with [list of [lists of 'strings' and [list of 'strings']]].

Recursively Generating a List of n choose k combinations in Python - BUT return a list

I'm attempting to generate all n choose k combinations of a list (not checking for uniqueness) recursively by following the strategy of either include or not include an element for each recursive call. I can definitely print out the combinations but I for the life of me cannot figure out how to return the correct list in Python. Here are some attempts below:
class getCombinationsClass:
def __init__(self,array,k):
#initialize empty array
self.new_array = []
for i in xrange(k):
self.new_array.append(0)
self.final = []
self.combinationUtil(array,0,self.new_array,0,k)
def combinationUtil(self,array,array_index,current_combo, current_combo_index,k):
if current_combo_index == k:
self.final.append(current_combo)
return
if array_index >= len(array):
return
current_combo[current_combo_index] = array[array_index]
#if current item included
self.combinationUtil(array,array_index+1,current_combo,current_combo_index+1,k)
#if current item not included
self.combinationUtil(array,array_index+1,current_combo,current_combo_index,k)
In the above example I tried to append the result to an external list which didn't seem to work. I also tried implementing this by recursively constructing a list which is finally returned:
def getCombinations(array,k):
#initialize empty array
new_array = []
for i in xrange(k):
new_array.append(0)
return getCombinationsUtil(array,0,new_array,0,k)
def getCombinationsUtil(array,array_index,current_combo, current_combo_index,k):
if current_combo_index == k:
return [current_combo]
if array_index >= len(array):
return []
current_combo[current_combo_index] = array[array_index]
#if current item included & not included
return getCombinationsUtil(array,array_index+1,current_combo,current_combo_index+1,k) + getCombinationsUtil(array,array_index+1,current_combo,current_combo_index,k)
When I tested this out for the list [1,2,3] and k = 2, for both implementations, I kept getting back the result [[3,3],[3,3],[3,3]]. However, if I actually print out the 'current_combo' variable within the inner (current_combo_index == k) if statement, the correct combinations print out. What gives? I am misunderstanding something to do with variable scope or Python lists?
The second method goes wrong because the line
return [current_combo]
returns a reference to current_combo. At the end of the program, all the combinations returned are references to the same current_combo.
You can fix this by making a copy of the current_combo by changing the line to:
return [current_combo[:]]
The first method fails for the same reason, you need to change:
self.final.append(current_combo)
to
self.final.append(current_combo[:])
Check this out: itertools.combinations. You can take a look at the implementation as well.

Adding object to a list with a for loop?

I've done my research on stack overflow and could not find an answer that works out for me even though similar questions have been posted in the past. My issue is that I want to add string values that I am getting from a for loop that goes through a list and matches to a regular expression. I want to add them to a combined list of values, I am using a clean function that works on the submission of a form but when the data prints into my terminal it comes out like this:
['#example']
['#test']
when I want those values to print like this:
['#example', '#test',]
Here's my code in my views.py
def clean(self):
data = self.cleaned_data
regex = re.compile("\B#\w\w+")
tweeters = data['tweets']
split_tweets = tweeters.split()
for x in split_tweets:
if re.search(regex, x):
master_list = [x]
print master_list
You need to append to a list, otherwise you are just throwing away all the previous values
def clean(self):
data = self.cleaned_data
regex = re.compile("\B#\w\w+")
tweeters = data['tweets']
split_tweets = tweeters.split()
master_list = []
for x in split_tweets:
if re.search(regex, x):
master_list.append(x)
print master_list
You can also use a list comprehension here instead
def clean(self):
data = self.cleaned_data
regex = re.compile("\B#\w\w+")
tweeters = data['tweets']
split_tweets = tweeters.split()
master_list = [x for x in split_tweets if re.search(regex, x)]
print master_list
You're doing some strange things with that assignment. Why do you keep reassigning a list? Initialize the list before the loop, append() to it inside the loop, and print the whole thing after the loop.
master_list = []
for x in split_tweets:
if re.search(regex, x):
master_list.append(x)
print master_list
Do this instead:
def clean(self):
data = self.cleaned_data
regex = re.compile("\B#\w\w+")
tweeters = data['tweets']
split_tweets = tweeters.split()
master_list = []
for x in split_tweets:
if re.search(regex, x):
master_list.append(x)
print master_list
You need to append elements to the list instead of affecting a new "one element list" [x] to master_list, it get overridden by the next value

Get list of data after recursion function

I need to run through db using recursion and get a list of results at the end. Function works correct (if print unrem) but I cann't return the list of results.
def find_locks(item, ids):
if item.video_id:
#print (item.video_id, ids)
return (item.video_id, ids)
for i in CatalogItem.objects.filter(parent=item):
if i.is_lock:
find_locks(i, ids.append(i.id))
else:
find_locks(i, ids)
How can I get the list results?
I'd use a recursive generator instead of building a list:
def find_locks(item, ids):
if item.video_id:
yield (item.video_id, ids)
for i in CatalogItem.objects.filter(parent=item):
nxt = ids + [i.id] if i.is_lock else ids
for x in find_locks(i, nxt):
yield x
In python 3.3 you can use yield from for the last part.
Try something like the following:
def find_locks(item, ids):
if item.video_id:
return [(item.video_id, ids)]
res = []
for i in CatalogItem.objects.filter(parent=item):
if i.is_lock:
res.extend(find_locks(i, ids + [i.id]))
else:
res.extend(find_locks(i, ids))
return res
In the base case you return list with the only one item included. If it's not the base case, you make a new list, execute recursive call, extend the list with result of recursive call and return this list.
You can simply store each result in a list and return that at the end:
def find_locks(item, ids):
if item.video_id:
return [(item.video_id, ids)]
result = []
for i in CatalogItem.objects.filter(parent=item):
if i.is_lock:
result.extend(find_locks(i, ids + [i.id]))
else:
result.extend(find_locks(i, ids))
return result
Note that you need to return each item in a list as well because other calls to find_locks expect to receive a list as return value.

Categories