I need to define a function called "len_score" that returns the length of a word. Call the "best" function with the len_score function as a parameter.
Output I want to be:
print(best(len_score, names), "has the longest name.")
McJagger has the longest name.
My code is:
def len_score(name):
lst=[len(x) for x in name]
return lst
def best(lst1,lst2):
final=zip(lst1,lst2)
return max final
names = ["Ben", "April", "Zaber", "Alexis", "McJagger", "J.J.", "Madonna"]
print(best(len_score, names) == 'McJagger')
But I got error and not sure how to set condition on the list.
I think what you're trying to do is:
def len_score(name):
lst = [len(x) for x in name]
return lst
def best(func, lst):
func_lst = func(lst) # call the passed in function ON lst
return lst[func_lst.index(max(func_lst))]
names = ["Ben", "April", "Zaber", "Alexis", "McJagger", "J.J.", "Madonna"]
print(best(len_score, names) == 'McJagger')
You are almost there:
def len_score(name):
lst=[len(x) for x in name]
return lst
def best(lst1,lst2):
final=zip(lst1,lst2)
return max(final)
names = ["Ben", "April", "Zaber", "Alexis", "McJagger", "J.J.", "Madonna"]
print(best(len_score(names), names)[1])
print(best(len_score(names), names)[1] == 'McJagger')
Working code: https://py3.codeskulptor.org/#user302_Lx3nAppYJe_0.py
Related
I'm trying to enumerate the list using recursion and am having a hard time doing so.
If anyone can point me in the right direction that would be greatly appreciated! :)
def my_enumerate(items, start_index=0):
"""my enumerate"""
result = []
if not items:
return []
else:
a = (start_index, items[0])
result.append(a)
my_enumerate(items[1:], start_index + 1)
return result
ans = my_enumerate([10, 20, 30])
print(ans)**strong text**
Try:
def my_enumerate(items, start_index=0):
"""my enumerate"""
result = []
if not items:
return []
else:
a = (start_index, items[0])
result.append(a)
result += my_enumerate(items[1:], start_index + 1) # here
return result
The following is more concise:
def my_enumerate(items, start_index=0):
"""my enumerate"""
return [(start_index, items[0])] + my_enumerate(items[1:], start_index + 1) if items else []
As you are using recursion and you are declaring result = [] within a function so everytime it simply gets empty so you lose all previous results.
If you want exactly this to work there is also another way that by making the result as global if you wanted to use that list globally like below:
result = []
def my_enumerate(items, start_index=0):
"""my enumerate"""
global result
if not items:
return []
else:
a = (start_index, items[0])
result.append(a)
my_enumerate(items[1:], start_index + 1)
return result
ans = my_enumerate([10, 20, 30])
print(and)
But #CocompleteHippopotamus answer will work when you don't want to use a global keyword.
I have a string which I want to convert to a nested dictionary in Python.
Example Input :
import copy
diff_str = "/pathConstraint/latency/latencyValue"
value = "low"
diff_arr = diff.split("/")
final_temp_dict = dict()
for elem in reversed(diff_arr):
if len(final_temp_dict) == 0:
final_temp_dict.setdefault(elem, value)
else:
temp_final_dict = copy.deepcopy(final_temp_dict)
final_temp_dict.setdefault(elem, temp_final_dict)
print (final_temp_dict)
While running this I face an error and I'm not getting the expected output.
The output needed is as a nested dictionary:
{"pathConstraint" : {"latency" : {"latencyValue" : "low"}}}
You could use the following recursive function:
def string_to_dict(keys, value):
key = keys.split('/')
if len(key) == 2:
return {key[1]: value}
else:
return string_to_dict('/'.join(key[:-1]), {key[-1]: value})
Output:
>>> string_to_dict(diff_str, value)
{'pathConstraint': {'latency': {'latencyValue': 'low'}}}
Note that this assumes that diff_str begins with a / character.
The following is an iterative approach. Note diff_arr[1:] is used to exclude the empty string that is generated from splitting on the initial /.
diff_str = "/pathConstraint/latency/latencyValue"
value = "low"
diff_arr = diff_str.split("/")
for key in list(reversed(diff_arr[1:])):
value = {key: value}
print(value)
Output
{'pathConstraint': {'latency': {'latencyValue': 'low'}}}
Shorter recursive approach:
def to_dict(d, v):
return v if not d else {d[0]:to_dict(d[1:], v)}
diff_str = "/pathConstraint/latency/latencyValue"
value = "low"
print(to_dict(list(filter(None, diff_str.split('/'))), value))
Output:
{'pathConstraint': {'latency': {'latencyValue': 'low'}}}
I tried to modify your function as little as possible, this should work just fine
import copy
def func():
diff_str = "/pathConstraint/latency/latencyValue"
value = "low"
diff_arr = diff_str.split("/")
final_temp_dict = dict()
for elem in reversed(diff_arr):
if elem == "":
continue
if len(final_temp_dict) == 0:
final_temp_dict[elem] = value
else:
temp_final_dict = copy.deepcopy(final_temp_dict)
final_temp_dict = {}
final_temp_dict[elem] = temp_final_dict
print (final_temp_dict)
However, there are much nicer ways to do something like this. See the other answers for inspiration.
def convert(items, value):
if not items:
return value
return {items.pop(0): convert(items, value)}
print(convert(diff_str.strip('/').split('/'), 'low'))
So I am still a beginner programmer who has been tasked with sorting objects created by a csv file with the attributes lname, fname, gender, age (in that order) and sort them by the lname attribute. I have achieved this, however I now need to delete one of the objects (I chose a random one to test) and this is what I have so far:
class FitClinic:
def __init__(self, lname, fname, gender, age):
self.lname = lname
self.fname = fname
self.gender = gender
self.age = int(age)
def __del__(self):
print("Customer has been deleted")
def get_lname(self):
return self.lname
def get_fname(self):
return self.fname
def get_gender(self):
return self.gender
def get_age(self):
return self.age
fh=open('fit_clinic_20.csv', 'r')
fh.seek(3)
listofcustomers=[]
for row in fh:
c = row.split(",")
listofcustomers.append(FitClinic(c[0], c[1], c[2], c[3]))
sorted_list=sorted(listofcustomers,key=lambda x: x.get_lname())
for x in sorted_list:
if x.get_lname()==("Appleton"):
del x
print(x.get_lname(),x.get_fname(),x.get_gender(),x.get_age())
now it obviously doesnt work and I need some help.
del x just deletes the temporary variable x, it has no effect on the list. You need to use del listofcustomers[pos], but first you have to find the position in the list.
try:
pos = next(i for i,v in enumerate(listofcustomers) if v.get_lname() == "Appleton")
del listofcustomers[pos]
except StopIteration:
pass // Ignore if not found
See Python: return the index of the first element of a list which makes a passed function true for numerous ways to find the index of an element that matches a criteria.
You can remove an item from a list with list comprehension:
sorted_list[:] = [x for x in sorted_list if not(x.get_lname()==("Appleton"))]
A working example:
class FitClinic:
def __init__(self, lname):
self.lname = lname
def __del__(self):
print("Customer has been deleted")
def get_lname(self):
return self.lname
# Create example
sorted_list = [FitClinic('a'), FitClinic('b'), FitClinic('c'), FitClinic('Appleton')]
sorted_list[:] = [x for x in sorted_list if not(x.get_lname()=="Appleton")]
Now sorted_list is.
a
b
c
This example is better with filter since it removes all clinics where lname is Appleton:
sorted_list = list(filter(lambda c: c.get_lname() != "Appleton", sorted_list))
If you want to remove only the first one, use Barmar's answer.
This is the same as a list comprehension, which Python is better at optimizing:
sorted_list = [c for c in sorted_list if c.get_lname() != "Appleton"]
Just Try this:
for x in sorted_list: # Loops through Customers in List
if x.get_lname() == "Appleton": # Check if the last name is Apple
sorted_list.remove(x) # Remove each from the list, Pretty self explanatory
else: # you only want to print if the last name is not APppleton
print(x.get_lname(), x.get_fname(), x.get_gender(), x.get_age())
.remove removes an object from a list so you do not need to track the index of the loop.
Read this w3schools tutorial for more list operations
I have the following python code to delete all the copies of a file in a certain directory keeping only one of them.
It works fine if i comment out the first four lines in the delete() function but if i don't it gives me a error that local variable list1 referenced before assignment. Also I tried using something called global but it didn't help me much as it gave error saying that it is NoneType.
Please help me i am just a intermediate beginner in Python.
list1 = []
list2 = []
def stripe(lis):
for i in range(len(lis)):
lis[0] = lis[0].strip()
def scan(pat):
pat = os.path.abspath(pat)
files = os.listdir(pat)
for file in files:
filepath = os.path.join(pat,file)
if os.path.isfile(filepath):
list1.append(file)
list2.append('{0}'.format(filepath))
elif os.path.isdir(filepath):
scan(filepath)
def delete():
list1_1 = stripe(list1)
list2_1 = stripe(list2)
list1 = list1_1
list2 = list2_1
length = len(list1)
#length = length - 1
i = 0
while i < length:
item = list1[0]
a = list1[0]
b = list2[0]
del list1[0]
del list2[0]
if item in list1:
try:
os.remove(list2[list1.index(item)])
#del list1[list1.index(item)]
#del list2[list1.index(item)]
except:
print('sorry',list1[0],'could not be deleted',sep = ' ')
print('wow')
i += 1
#list1.append(a)
#list2.append(b)
global looks like the right option for you, but if you say it gives error, use the way that comes to mind first. list1 and list2 can be the parameters of the delete() function.
Something like this:
def delete(list1, list2):
...
def foo():
list1 = []
list2 = []
...
delete(list1, list2)
Also, as I said, global is always an option. Here is an easy example:
list = []
def foo():
global list
list.append(1234)
def foo2():
global list
print(list)
foo()
foo2()
Output:
[1234]
In python, I have a list of classes that have a string field called category.
Let's consider the following example:
mylist[0].category # = "furniture"
mylist[1].category # = "car"
mylist[2].category # = "fruit"
mylist[3].category # = "car"
mylist[4].category # = "furniture"
My question is: how to reorder the list by grouping using the first occurence of a new category ?
Using the previous example, the result would be:
mylist[0].category # = "furniture"
mylist[1].category # = "furniture"
mylist[2].category # = "car"
mylist[3].category # = "car"
mylist[4].category # = "fruit"
First, get a list of the categories in the same order as my_list. Then, sort my_list according to the position of the first appearance of each item's category in the list of categories.
categories = [item.category for item in my_list]
my_list.sort(key = lambda item: categories.index(item.category))
# create a first-appearance index
order = {}
for ndx,item in enumerate(mylist):
if item.category not in order:
order[item.category] = ndx
# sort by that index
mylist.sort(key=lambda i: order[i])
you may achieve this by traversing the list twice ( no sorting ):
from collections import defaultdict
# put all the items of the same category together
l = defaultdict( list )
for x in mylist:
l[ x.category ].append( x )
# expand in the order categories appear in the list
xs = [ ]
for x in mylist:
xs.extend( l[ x.category ] )
l.pop( x.category )
Perhaps something like this?
#!/usr/local/cpython-3.3/bin/python
import pprint
CATEGORY_FIRST_SEEN = {}
def extract_order(list_of_class):
for index, element in enumerate(list_of_class):
if element.category not in CATEGORY_FIRST_SEEN:
CATEGORY_FIRST_SEEN[element.category] = index
#pprint.pprint(CATEGORY_FIRST_SEEN)
class Class_with_category:
def __init__(self, category):
self.category = category
def __cmp__(self, other):
if CATEGORY_FIRST_SEEN[self.category] < CATEGORY_FIRST_SEEN[other.category]:
return -1
elif CATEGORY_FIRST_SEEN[self.category] > CATEGORY_FIRST_SEEN[other.category]:
return 1
else:
return 0
def __lt__(self, other):
return self.__cmp__(other) < 0
def __str__(self):
return self.category
__repr__ = __str__
def main():
mylist = [ "furniture", "car", "fruit", "car", "furniture", ]
list_of_class = [ Class_with_category(element) for element in mylist ]
extract_order(list_of_class)
list_of_class.sort()
pprint.pprint(list_of_class)
main()
I've tested it to work on cpython 3.3, but I believe it should work on 2.x or 3.x.