How does list1 == list2.reverse() gets executed in python? - python-3.x

I am trying to compare two lists(as shown) and I have written a code based on my own logic. According to my logic I have to get output as 'Yes' but I am getting 'No' as output. I think there is something wrong in line3 of my code. According to my logic, in line 3, list2 gets reversed first and then it is compared with list1. With this logic, I have to get output as 'Yes'. Is my logic correct? If not please help me how line3 gets executed.(I am new to python)
list1 = ['a','m','y']
list2 = ['y','m','a']
if list1 == list2.reverse():
print('Yes')
else:
print("No")
Given Output: No;
Expected Output: Yes

list2.reverse() will not return anything i.e. None, but it modifies your list
below is the correct code:
list1 = ['a','m','y']
list2 = ['y','m','a']
list2.reverse()
if list1 == list2:
print('Yes')
else:
print("No")

because list2.reverse() returns 'None' and it change list2to ['a','m','y']. Use this ->
list2 = ['y','m','a']
list2.reverse()
if list1 == list2:
print('Yes')
else:
print("No")

you might code like below:
list1 = ['a','m','y']
list2 = ['y','m','a']
list2.reverse()
if list1 == list2:
print('Yes')
else:
print("No")
>>> Yes
Or like this:
list1 = ['a','m','y']
list2 = ['y','m','a']
if list1 == list(reversed(list2)):
print('Yes')
else:
print("No")

Related

Why return node.next will return the whole linked list?

I am new to coding and am working on LeetCode#21 Merge two sorted list.
An example:
Input: list1 = [1,2,4], list2 = [1,3,4]
Output: [1,1,2,3,4,4]
A common solution to this question is:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def mergeTwoLists(self, list1: ListNode, list2: ListNode) -> ListNode:
dummy = ListNode()
tail = dummy
while list1 and list2:
if list1.val < list2.val:
tail.next = list1
list1 = list1.next
else:
tail.next = list2
list2 = list2.next
tail = tail.next
if list1:
tail.next = list1
elif list2:
tail.next = list2
return dummy.next
I am confused with the last line: return dummy.next
Shouldn't it simply return the next node of dummy node?
How will that return the whole list?
Dummy is created as a temporary head, because at the start we don't know whether our head starts with list1 or list2.
After we are done merging, dummy will look like this. The dummy value is 0 because this is the default value when you call ListNode().
0 > 1 > 1 > 2 > 3 > 4 > 4
But our original list does not have 0, therefore 0 is removed by dummy.next
dummy.next will look like this.
1 > 1 > 2 > 3 > 4 > 4
This will return the whole list because each ListNode stores its next value in the self.next property.
You can check with this. We know we have reached the end node of the linked list when its self.next is None.
current = dummy.next;
while current is not None:
print(current.val);
current = current.next;

How to represent these singly linked list nodes in the leetcode test runner in a Python script?

I am struggling with these linked list problems on leetcode (and the tree problems since they use a similar structure). Example https://leetcode.com/problems/merge-two-sorted-lists/
If I try to run this code outside of leetcode's magic box, I run into issues.
My mergeTwoLists function works great inside of the leetcode editor (runs successfully, is accepted)
from typing import Optional
# Definition for singly-linked list.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def mergeTwoLists(list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
prehead = ListNode(-1)
prev = prehead
while list1 and list2:
if list1.val <= list2.val:
prev.next = list1
list1 = list1.next
else:
prev.next = list2
list2 = list2.next
prev = prev.next
breakpoint()
prev.next = list1 if list1 is not None else list2
return prehead.next
if __name__ == '__main__':
l1 = ListNode(1)
l1_2 = ListNode(2)
l1_3 = ListNode(4)
l1.next = l1_2
l1_2.next = l1_3
l2 = ListNode(1)
l2_2 = ListNode(3)
l2_3 = ListNode(4)
l2.next = l1_2
l2_2.next = l1_3
print(mergeTwoLists(l1, l2))
The problem is that when I try to run the above standalone from my terminal it gets into an infinite loop.
The reason is that due to what I have passed into the function, if I throw a breakpoint() into the end of the first loop and inspect list1 and list2
(Pdb) list1
<__main__.ListNode object at 0x00000294E1F8FEE0>
(Pdb) list2
<__main__.ListNode object at 0x00000294E1F8FE20>
Which makes sense. It explains the infinite loop, class objects eval to True when cast to bool.
So based on this, if I want to get this code to run outside leetcode I need to do something differently. I need more info for my class definition, or my test case setup is wrong?
Does anyone know more about the complete definition of the ListNode class in Leetcode's system? Or is there something I am missing in how I should be setting up my test?
Thank you!
So yes, you are correct, on your while list1 and list2 this evaluates to True.
You can solve it like this, being more explicit:
def mergeTwoLists(list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
prehead = ListNode(-1)
prev = prehead
while (list1.next is not None) and (list2.next is not None):
if list1.val <= list2.val:
prev.next = list1
list1 = list1.next
else:
prev.next = list2
list2 = list2.next
prev = prev.next
prev.next = list1 if list1 is not None else list2
return prehead.next
It probably works in leetcode because they defined another method to the class. If you define the class like this:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def __bool__(self):
"""Return bool(self)."""
return self.next is not None
Then the __bool__ method will be called when you try to do list1 and list2, and it does the same behavior.

Create a list that returns only palindromes from a list of numbers

I'm working on creating a program that will first check if numbers in the list are palindromes and then prints out only the palindromes. I am new to Python so I'm not sure how to properly append these to a new list.
inp= input()
list1 = []
while int(inp) != 0:
list1.append(inp)
inp= input()
def isPalindrome(N):
str1 = "" + str(N)
len1 = len(str1)
for i in range(int(len1 / 2)):
if (str1[i] != str1[len1 - 1 - i]):
return False
return True
list2 = []
for i in list1:
if i == isPalindrome:
list2.append(i(list1))
print(list2)
For example,
Input:
99
23
45
1221
0
Output:
99 1221
You just have some syntax errors in your code but your logic is correct..
Here is what you intended to do,
inp= int(input())
list1 = []
while inp != 0:
list1.append(inp)
inp = int(input())
def isPalindrome(N):
str1 = "" + str(N)
len1 = len(str1)
for i in range(int(len1 / 2)):
if (str1[i] != str1[len1 - 1 - i]):
return False
return True
list2 = []
for i in list1:
if isPalindrome(i):
list2.append(i)
print(list2)
Also if you want to make your program much shorter than i recommend this,
def isPalindrome(N):
str1 = str(N)
if str1[::-1] == str1:
return True
else:
return False
Just a slight change in synatx but logic is though same as yours. It uses string slicing in reverse direction.
Also i have type casted the input to integers using int(input()) as you said you need numbers to be printed in list2, if you don't want integers then just replace all int(input()) with input() and change your if condition to int(inp)!=0 at beginning

Building a dictionary with lists using recursion

I was trying to build a dictionary with recursion for a school project. Right now I think I have the general structure figured out, but I can't figure out how to get the return statement to concatenate pieces of the dictionary together.
I realize this would probably be easier by constructing an empty dictionary then adding to it, but I wanted to see if there were any tricks I could use.
The output I was looking for is:
print(recur_join([1,2,3], ['a', 'b', 'c']))
>>> {1: 'a', 2 : 'b', 3 : 'c'}
I have tried .update() and something of the form dict(basket_one, **basket_two) from another answer. I may have used them wrong. I am using python 3.
Here is my code as of now:
def recur_join(list1, list2):
if len(list1) == len(list2):
if len(list1) == 1:
return {list1[0]: list2[0]}
elif len(list1) > 1:
# dict(basket_one, **basket_two)
#return dict({list1[0]: list2[0]}, **recur_join(list1[1:],
list2[1:]))
return {list1[0]: list2[0]}.update(recur_join(list1[1:], list2[1:]))
else:
print('lists do not match in size')
return 0
Any help would be appreciated, sorry if this was answered before.
Thanks!
I suggest you don't use recursion and use dict comprehensions instead:
def recur_join(list1, list2):
if len(list1) != len(list2):
print('lists do not match in size')
return
else: return {list1[i]:list2[i] for i in range(len(list1))}
For the recursive route (warning: very ugly):
def recur_join(list1, list2):
if len(list1) != len(list2):
print('lists do not match in size')
return
elif list1 == [] and list2 == []:
return {}
else:
return dict(list({list1[0]: list2[0]}.items()) + list(recur_join(list1[1:], list2[1:]).items()))
"Cleanish" recursive solution. I would personally use Primusa's dictionary
comprehension solution.
def recur_join(list1, list2):
cur = {}
if len(list1) == len(list2) and len(list1) > 0:
cur = {list1[0]: list2[0]}
if len(list1) > 1:
cur.update(recur_join(list1[1:], list2[1:]))
else:
print('lists do not match in size')
return cur

How can I compare lists and repeat a task till the lists from previous and current iteration are equal?

I want to append elements to two separate lists. It should continue till set(list1 of previous iteration) == set(list1 of this iteration), and set(list2 of previous iteration) == set(list2 of this iteration). So far I have this. It's looping infinitely, and I don't understand what am I doing wrong?
list1 = []
list2 = []
while True:
prev_list1 = []
prev_list2 = []
for x in my_list:
if x == 'A':
list1.append(x)
elif x == 'B':
list2.append(x)
if set(list1) == set(prev_list1) and set(list2) == set(prev_list2):
break
Nevermind. I spotted the mistake. I was not updating the previous lists!
while True:
prev_list1 = list1
prev_list2 = list2

Resources