I have this function that I need to compare the strings in a list to a *args
The reason being is that, the user should be able to type any words in the 2nd argument. However when I try to compare the strings to the *args it doesn't give me any results
def title_case2(title, *minor_words):
for x in title.split():
if x in minor_words:
print(x)
Assuming I ran the function with the parameters below. I was hoping it would display a and of since these words are found on those 2 entries.
title_case2('a clash of KINGS','a an the of')
*args is a tuple of arguments, so you're actually checking if x is in ('a an the of',). So either pass your argument as:
title_case2('a clash of KINGS', *'a an the of'.split())
Or, use this as your test:
if any(x in y for y in minor_words):
In either of the above cases the output is:
a
of
This is one approach.
Ex:
def title_case2(title, *minor_words):
minor_words = [j for i in minor_words for j in i.split()] #Create a flat list.
for x in title.split():
if x in minor_words:
print(x)
title_case2('a clash of KINGS','a an the of', "Jam")
using a for-loop instead of list comprehension
def title_case2(title, *minor_words):
minor_words_r = []
for i in minor_words:
for j in i.split():
minor_words_r.append(j)
for x in title.split():
if x in minor_words_r:
print(x)
Related
The function must return a list consisting of the numbers greater than the second number in the function
It must be able to do the following when functioning:
returnGreater([1,2,3,4,5], 3)
[4,5]
returnGreater([-8,2,-4,1,3,-5],3)
[]
Here's what I have (I've gone through a few iterations), though I get a Type Error for trying to use a ">" symbol between an int and list:
def returnGreater (x,y):
"x:list(int) , return:list(int)"
#greater: int
greater = []
for y in x:
#x: int
if x > y:
x = greater
return greater
You're using the name y for two different things in your code. It's both an argument (the number to compare against) and the loop variable. You should use a different name for one of those.
I'd strongly suggest picking meaningful names, as that will make it much clearer what each variable means, as well as making it much less likely you'll use the same name for two different things. For instance, here's how I'd name the variables (getting rid of both x and y):
def returnGreater(list_of_numbers, threshold):
greater = []
for item in list_of_numbers:
if item > threshold:
greater.append(item)
return greater
You had another issue with the line x = greater, which didn't do anything useful (it replaced the reference to the original list with a reference to the empty greater list. You should be appending the item you just compared to the greater list instead.
I recommend filter. Easy and Graceful way.
def returnGreater(x, y):
return list(filter(lambda a:a>y, x))
It means, filter each element a in list x using lambda whether a is greater than y or not.
List Comprehensions
def returnGreater(_list, value):
return [x for x in _list if x > value]
Given this list of tuples:
my_tuples = [(1,2), (3,4)]
and the following evaluation function:
def evaluate(item_tuple):
return item_tuple[0] * 2
Question: how can I get the list item (tuple) that has the highest evaluation value? (I'm guessing I can use a list comprehension for this)
def max_item(tuples_list, evaluation_fn):
'''Should return the tuple that scores max using evaluation_fn'''
# TODO Implement
# This should pass
assertEqual((3,4), max_item(my_tuples, evaluate))
Correct me if I'm wrong, you want the list of tuples sorted by the result of multiplying one of the values inside the tuple with x (in your example above it would be the first value of the tuple multiplied by 2).
If so, you can do it this way:
from operator import itemgetter
sorted(l, key=itemgetter(0 * 2), reverse=True)
I managed to do it this way:
def max_item(tuples_list, evaluation_fn):
zipped = zip(map(evaluation_fn, tuples_list), tuples_list)
return max(zipped, key=lambda i:i[0])[1]
I don't know if there's a simpler (more pythonic?) way to solve it though.
Edit
I figured how I could use a list comprehension to make it more succinct/readable:
def max_item(tuples_list, evaluation_fn):
return max([(evaluation_fn(i), i) for i in tuples_list])[1]
You know when you find a solution via trial and error but you stumbled so much thtat you can't understand the answer now?
Well this is happening to me with this piece:
entr = [list(int(x) for x in input().split()) for i in range(int(input()))]
The input is done by copying and pasting this whole block:
9
8327 0
0070 0
2681 2
1767 0
3976 0
9214 2
2271 2
4633 0
9500 1
What is my list comprehension exactly doing in each step? And taking into account this: How can I rewrite it using for loops?
In fact, your code is not a nested list-comprehension, beause you use list construtor rather than mere list-comprehension.
This line serves as same as your code:
entr = [[int(x) for x in input().split()] for i in range(int(input()))]
To understand this line, you must remember the basic structure of list-comprehension in python, it consists of two component obj and condition with a square brackets surrounding:
lst = [obj condition]
it can be converted to a loop like this:
lst = []
condition:
lst.append(obj)
So, back to this question.
What you need to do now is to break the nested list-comprehension into loop in loop, usually you begin from the condition in latter part, from outer space to inner space. You got:
entr = []
for i in range(int(input())):
entr.append([int(x) for x in input().split()])) # the obj is a list in this case.
And now, you can break the list-comprehension in line 3.
entr = []
for i in range(int(input())):
entry = []
for x in input().split():
entry.append(int(x))
entr.append(entry)
So, now the stuff the original line can be easily understand.
the program construct a entry list named entr;
the program ask for user input and convert the input string into an int, which is the number of the entrys you want to input(assume it is num);
the program ask for user input for num times, each time you should input something seperate with spaces.
The program split every string into a list (named entry in above code) you input with str.split() method (with parameter sep default to space). And append each entry list in every loop.
for every element in the entry list, it converted to int.
My English may be poor, feel free to improve my answer:)
That is equivalent to this:
entr = []
for i in range(int(input())):
row = []
for x in input().split():
row.append(int(x))
entr.append(row)
You can copy-paste that into a list comprehension in a couple steps. First the inner loop/list:
entr = []
for i in range(int(input())):
row = [int(x) for x in input().split()]
entr.append(row)
Without the row variable:
entr = []
for i in range(int(input())):
entr.append([int(x) for x in input().split()])
Then the outer loop/list (copied over multiple lines for clarity):
entr = [
[int(x) for x in input().split()]
for i in range(int(input()))
]
You have that same nested comprehension except that the inner one has been written as a generator passed to the list constructor so it looks like list(int(x) for x in input().split()) instead of [int(x) for x in input().split()]. That's a little more confusing than using a list comprehension.
I hope that explanation helps!
I would like to turn this code into a list comprehension:
l = list()
for i in range(10):
j = fun(i)
if j:
l.append(j)
Meaning that I'd like to add only truthy fun() result values to the list. Without the truthy check of that function call, the list comprehension would be:
l = [fun(i) for i in range(10)]
Adding a if fun(i) to the list comprehension would cause two evaluations of fun() per iteration (actually, not always it seems!), thus causing unintended side effects if fun() is not pure.
Can I capture the result of fun(i) and use it in that same comprehension, essentially adding the if j? (Related question here)
You can make an inner generator in the list comp so you will look over the results of func
l = [j for j in (func(i) for i in range(10)) if j]
Or combining two suggested solutions:
filter(None, (func(i) for i in range(10)))
Edit
Much simpler:
[res for res in map(func, range(10)) if res]
Thanks for the hint to falstru.
Old answer
Another option would to use a helper generator function:
def call_iter(func, iterable):
for arg in iterable:
yield func(arg)
[res for res in call_iter(func, range(10)) if res]
is it possible to create a list of exact 3 elements?
I wan to create an list (or may be tuple) for exact the elements (coordinates in 3-d).
I can do it as:
nhat=input("Enter coordinate\n")
the problem is that it will take any number (even greater or less then 3).
But it will be good if I have it prompting for number if it is <3 and exit when 3 value is given.
Edit
what I am currently doing is:
nhatx=input("Enter x-coordinate\n")
nhaty=input("Enter y-coordinate\n")
nhatz=input("Enter z-coordinate\n")
and then making the nhat list made of nhat{x,y,z}. Just thinking if I can define a list of predefined dimension, so that I don't need those nhat{x} variables
You could try something like:
def get_coords():
while True:
s = input("Enter coordinates (x y z): ")
try:
x, y, z = map(float, s.split())
except ValueError: # wrong number or can't be floats
print("Invalid input format.")
else:
return x, y, z
Now your code becomes:
nhatx, nhaty, nhatz = get_coords() # unpack tuple
or
nhat = get_coords() # leave coords in tuple