Make list comprehension of this for loop, Python - python-3.x

I'm matching first value of a pair in tuples, and returning the second value if the first value matches across tuples. The code I wrote is working but I want to make it more pythonic, this code looks overly long:
def intersect(A, B):
setx = set()
for i in A:
i, y = i[0], i[1]
for x in B:
if i in x:
x = x[1]
setx.add((y,x))
print(setx)
return setx
Now I execute function in interpreter and get the result I want:
intersect(
{ (8, 'huit'),
(10, 'dixA'),
(12, 'douze')},
{ (5, 'cinq'),
(10, 'dixB'),
(15, 'quinze')})
and the output shows:
{('dixA', 'dixB')}
I try to get fancy and try to clean up the code:
def intersect(A, B):
setx = set()
for i in A:
i, y = i[0], i[1]
c = x for x in B if i in x
#x = c[1]
setx.add((y,x))
print(setx)
return setx
The above code gives me an invalid syntax error. When I create a list comprehension
[x[1] for x in B if i in x]
It returns a list and I cant add lists using the add method of set. Would someone be able to help me clean up my code a bit?

Interestingly this worked, I haven't used the double ++ sign in a while:
def intersect(A, B):
setx = set()
for i in A:
for x in B:
if i[0] == x[0]:
setx.add(i[1]), setx.add(x[1])
return setx

Related

Values in list are sometimes switching and i dont know why

I'm programming a length conversion calculator in python. I will convert the input to a sheet. Then I compare the input (as a set) with the dictionary and pull the appropriate values. My problem is that sometimes the values in the list are stored in the opposite order than they should be. For example mm -> m should always be stored as [0, 3] in the list but sometimes it gets switched [3, 0] and I don't know why. I tried the import -> Orderedlist method. Still the same problem. Here is my code.
def prevod_delky():
x = None #vstup format list
y = None
z1 = {'mm':0, 'cm':1, 'dm':2, 'm':3}
x = input('Enter the value and conversion units. E.g. mm -> cm. \n')
x = x.lower().split(' ', 2)
try:
x[0].replace('.', '', 1).isdigit()
x[0] = float(x[0])
except:
print('Enter only digits!')
prevod_delky()
try:
y = {k: z1[k] for k in z1.keys() & set(x)}
y = list(y.values())
except:
print('Something went wrong!')
prevod_delky()
try:
a = abs(int(y[0] - y[1]))
if y[0] > y[1]:
for y in range(0, a):
x[0] = x[0] * 10
else:
for y in range(0, a):
x[0] = x[0] / 10
except:
print('Something went wrong')
finally:
print('The resulting length is {} {}'.format(x[0], x[2]))
prevod_delky()
I tried the import -> Orderedlist method.
I checked Python version (using 3.8.1)

I expect same output I want to remove letters from a list

I expect same result from these codes what wrong with the other one.
def remove_letters(list):
x = []
for i in range(len(list)):
if type(list[i]) == type(1):
x.append(list[i])
print(x)
return x
y = [1,'b', 'c',2]
remove_letters(y)
Output >> [1,2]
def remove_letters(list):
x = list
for i in range(len(list)):
if type(list[i]) == type('a'):
x.remove(list[i])
print(x)
return x
y = [1,'b', 'c',2]
remove_letters(y)
output>>
Traceback (most recent call last):
File "/Users/genesissales/PycharmProjects/1. Unbuquity [ 1, a, b, 2]/main.py", line 14, in <module>
remove_letters(y)
File "/Users/genesissales/PycharmProjects/1. Unbuquity [ 1, a, b, 2]/main.py", line 6, in remove_letters
if type(list[i]) == type('a'):
IndexError: list index out of range
Process finished with exit code 1
its giving an error. it seems that list is also being change by the
for loop.
I have edited the code to make it more readable and pythonic.
from copy import copy
# don't use list as variable name, it's a reserved keyword
def remove_letters(l): # actually only keeps integers
x = []
for item in l:
if isinstance(item, int):
x.append(item)
print(x)
return x
y = [1,'b', 'c',2]
remove_letters(y)
#Output >> [1,2]
def remove_letters(l): # does remove all strings
x = copy(l) # make a copy otherwise the y list from the outer scope is going to be altered! see https://stackoverflow.com/a/47264416/10875953
for i, item in reversed(list(enumerate(x))): # iterate in reverse order that way it doesn't matter if we delete, enumerate adds the index
if isinstance(item, str):
x.remove(i)
print(x)
return x
y = [1,'b', 'c',2]
remove_letters(y)

List comprehention works but normal for loop doesn't - Python

I defined a function to change an element of a list to be number 0, if this element is not a number. It works using list comprehension but it doesn't work when I use a normal for loop.
I'm trying to understand what's is the error in the for loop.
See the code below:
def zerozero(mylist):
mylist = [0 if type(x) == str else x for x in mylist]
return mylist
def zerozero2(mylist):
for x in mylist:
if type(x) == str:
x = 0
else:
x = x
return mylist
Your second function is not quite equivalent. You would need something like this:
def zerozero2(mylist):
new_list = []
for x in mylist:
if type(x) == str:
new_list.append(0)
else:
new_list.append(x)
return new_list
In this manner you can mimic the functionality of the list comprehension, creating a new list and appending items to it as you iterate through.
If you want to modify your list 'in place', you can use this sort of construction:
for idx, x in enumearte(mylist):
if type(x) == str:
mylist[idx] = 0
else:
mylist[idx] = x
However, practically speaking this is unlikely to have much impact on your code efficiency. You can't do this with a list comprehension, and in either case you can just re-assign the new list back to your original variable when you return from the function:
mylist = zerozeroX(mylist)
So what happens is your function is returning the same list as your input.
What you should do is create an empty list first. For example my_list_0 = [].
def zerozero2(mylist):
my_list_0 = []
for x in mylist:
if type(x) == str:
x=0
else:
x=x
my_list_0.append(x)
return my_list_0
The list comprehension essentially returns the new values into your original list, so this is why it is different.

name 'count' is not defined in python

I have this code in python and I am trying to make a counter for the iteration of the binary search (yeah I know it is incomplete...), but I am stuck with the variable inside the function, when i try to print the variable count I get this error
name 'count' is not defined in python
can someone explain why i get this error?
import csv
def binarySearch(arr, l, r, x):
count=0
while l <= r:
mid = int(l + (r - l) / 2)
# Check if x is present at mid
if arr[mid] == x:
return mid
# If x is greater, ignore left half
elif arr[mid] < x:
l = mid + 1
# If x is smaller, ignore right half
else:
r = mid - 1
# If we reach here, then the element
# was not present
return -1
with open('bl_printed_music_500.csv', newline='', encoding="utf-8-sig") as csvfile:
reader = csv.DictReader(csvfile)
arr=[]
for row in reader:
if row ["Publication date (standardised)"] != "":
arr.append(int(row["Publication date (standardised)"])) #create list for searching
list.sort(arr) #list must be sorted to work
#print (arr)
x = 1850 #year to search
# Function call
result = binarySearch(arr, 0, len(arr) - 1, x)
found = False
if result != -1:
found = True
print(found)
print(count)
I think it's because you defined count in binarySearch but try to use it outside of the method. Try using a global variable (define it outside of binarySearch), it should work.
You can return count as well.
For example:
def myFunc():
x = 5
y = 10
return x,y
a, b = myFunc()
print(a)
print(b)
This will be:
5
10
Note that, I could have written x, y = myFunc(). These x and y are not the same as the ones inside myFunc(). The latter are local to the function.
In your code, you can return your local count variable:
return mid, count #(A)
return -1, count #(A)
And get its value by:
result, count = binarySearch(arr, 0, len(arr)-1, x) #(B)
Again, these two count variables, (A) and (B) are different variables with different scopes.
See, for instance:
https://docs.python.org/3/faq/programming.html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value
Alternatively, if a global variable, as suggested in the other answer, suits you best, you can see an example of its usage in the link.

Checking if three inputs form a triangle

So I want to take three inputs from the user and check whether they form a triangle.Now I want my program to check using any three random values of of the given inputs and check whether a + b > c.Here is my code for that :
def check_triangle(a, b, c):
a, b, c = [float(i) for i in input('Enter the stick lengths: ').split(' ')]
x, y, z = [int(num) for num in [a, b, c]]
list_1 = [x, y, z]
def is_triangle(x, y, z):
for i in list_1:
if (list_1[i] <(list_1[i+1] + list_1[i+2])):
print("Yes")
else:
print("No")
check_triangle(a, b, c)
But I am getting no output.
What is the error
Your are getting no output, because you defined a function inside a function, but you are calling only the first one. So second one is defined but never executed. What you want to do to execute the second one is to add a function call at the end of the first one, so in your case it would be:
def check_triangle(a, b, c):
a, b, c = [float(i) for i in input('Enter the stick lengths: ').split(' ')]
x, y, z = [int(num) for num in [a, b, c]]
list_1 = [x, y, z]
def is_triangle(x, y, z):
for i in list_1:
if (list_1[i] <(list_1[i+1] + list_1[i+2])):
print("Yes")
else:
print("No")
is_triangle(x,y,z)
Indentation can be messed up, because I'm answering on my phone, sorry for that.
Also, from what I can see you will be getting list index out of range error at this line.
if (list_1[i] <(list_1[i+1] + list_1[i+2]))
That is happening because your i is actually an element of your list as defined in the line below, not an index, but you are trying to get an element from the list by it's index with the syntax my_list[index].
for i in list_1
What you want to do instead of the for loop mentioned above is iterate in the range of it's length, meaning iterate over possible indexes in the list, is done like so:
for i in range(len(list_1))
I notice a few other things in your code and a lot of room for improvement, but I hope you can deal with the rest yourself!
you are taking input from the user so you do not need to pass any arguments for your function check_triangle:
def is_triangle(x, y, z):
if x < y + z:
print("Yes")
else:
print("No")
def check_triangle():
x, y, z = map(int, input('Enter the stick lengths: ').split())
is_triangle(x, y, z)
check_triangle()
or you can simplify you code like:
def is_triangle(x, y, z):
print('Yes' if x < y + z else 'No')
is_triangle(*map(int, input('Enter the stick lengths: ').split()))
To begin, since a, b and c are variables input by the user, they do not need to be input into the function as arguments. In fact, because they are not defined before being given as arguments to the function, it is causing the function to raise a NameError with the message name 'a' is not defined when it is called. To fix this issue, you can remove a, b and c as arguments to your function in both its definition and its usage.
At this point, the function will run, but even if the user inputs the numbers in the format which your program is expecting (i.e. separated by single spaces - which is not explicitly specified to the user) the portion of your program that evaluates your target condition will not run because it is contained within the function is_triangle(x, y, z) which is not called. This function can be eliminated and your test condition can be evaluated within the main function. Additionally, there is no need to loop through the elements in the list as you can access its elements directly to evaluate your target condition.
Here is the code with these changes made:
# since a, b and c are given by the user, they do not need to be arguments to the function
def check_triangle():
a, b, c = [float(i) for i in input('Enter the stick lengths: ').split(' ')]
x, y, z = [int(num) for num in [a, b, c]]
list_1 = [x, y, z]
# evaluate your test condition directly within the main function. no secondary function is necessary
# as you want to check that c < a + b, access those elements directly by using the index of the list. no loop is necessary
if list_1[2] < list_1[0] + list_1[1]:
print("Yes")
else:
print("No")
# since a, b and c are not defined before running the function, they cause it to raise a NameError if they are given
check_triangle()
This code will run and evaluate your target condition. However, this condition (that c < a + b) does not (to my knowledge) actually mean that something is a triangle. Good luck and happy coding!

Resources