What does this input via list-comprehension do? - python-3.x

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!

Related

Palindrome problem - Trying to check 2 lists for equality python3.9

I'm writing a program to check if a given user input is a palindrome or not. if it is the program should print "Yes", if not "no". I realize that this program is entirely too complex since I actually only needed to check the whole word using the reversed() function, but I ended up making it quite complex by splitting the word into two lists and then checking the lists against each other.
Despite that, I'm not clear why the last conditional isn't returning the expected "Yes" when I pass it "racecar" as an input. When I print the lists in line 23 and 24, I get two lists that are identical, but then when I compare them in the conditional, I always get "No" meaning they are not equal to each other. can anyone explain why this is? I've tried to convert the lists to strings but no luck.
def odd_or_even(a): # function for determining if odd or even
if len(a) % 2 == 0:
return True
else:
return False
the_string = input("How about a word?\n")
x = int(len(the_string))
odd_or_even(the_string) # find out if the word has an odd or an even number of characters
if odd_or_even(the_string) == True: # if even
for i in range(x):
first_half = the_string[0:int((x/2))] #create a list with part 1
second_half = the_string[(x-(int((x/2)))):x] #create a list with part 2
else: #if odd
for i in range(x):
first_half = the_string[:(int((x-1)/2))] #create a list with part 1 without the middle index
second_half = the_string[int(int(x-1)/2)+1:] #create a list with part 2 without the middle index
print(list(reversed(second_half)))
print(list(first_half))
if first_half == reversed(second_half): ##### NOT WORKING BUT DONT KNOW WHY #####
print("Yes")
else:
print("No")
Despite your comments first_half and second_half are substrings of your input, not lists. When you print them out, you're converting them to lists, but in the comparison, you do not convert first_half or reversed(second_half). Thus you are comparing a string to an iterator (returned by reversed), which will always be false.
So a basic fix is to do the conversion for the if, just like you did when printing the lists out:
if list(first_half) == list(reversed(second_half)):
A better fix might be to compare as strings, by making one of the slices use a step of -1, so you don't need to use reversed. Try second_half = the_string[-1:x//2:-1] (or similar, you probably need to tweak either the even or odd case by one). Or you could use the "alien smiley" slice to reverse the string after you slice it out of the input: second_half = second_half[::-1].
There are a few other oddities in your code, like your for i in range(x) loop that overwrites all of its results except the last one. Just use x - 1 in the slicing code and you don't need that loop at all. You're also calling int a lot more often than you need to (if you used // instead of /, you could get rid of literally all of the int calls).

Python: what is the good practice to remove all elements in the list? [duplicate]

It seems so "dirty" emptying a list in this way:
while len(alist) > 0 : alist.pop()
Does a clear way exist to do that?
This actually removes the contents from the list, but doesn't replace the old label with a new empty list:
del lst[:]
Here's an example:
lst1 = [1, 2, 3]
lst2 = lst1
del lst1[:]
print(lst2)
For the sake of completeness, the slice assignment has the same effect:
lst[:] = []
It can also be used to shrink a part of the list while replacing a part at the same time (but that is out of the scope of the question).
Note that doing lst = [] does not empty the list, just creates a new object and binds it to the variable lst, but the old list will still have the same elements, and effect will be apparent if it had other variable bindings.
If you're running Python 3.3 or better, you can use the clear() method of list, which is parallel to clear() of dict, set, deque and other mutable container types:
alist.clear() # removes all items from alist (equivalent to del alist[:])
As per the linked documentation page, the same can also be achieved with alist *= 0.
To sum up, there are four equivalent ways to clear a list in-place (quite contrary to the Zen of Python!):
alist.clear() # Python 3.3+
del alist[:]
alist[:] = []
alist *= 0
You could try:
alist[:] = []
Which means: Splice in the list [] (0 elements) at the location [:] (all indexes from start to finish)
The [:] is the slice operator. See this question for more information.
it turns out that with python 2.5.2, del l[:] is slightly slower than l[:] = [] by 1.1 usec.
$ python -mtimeit "l=list(range(1000))" "b=l[:];del b[:]"
10000 loops, best of 3: 29.8 usec per loop
$ python -mtimeit "l=list(range(1000))" "b=l[:];b[:] = []"
10000 loops, best of 3: 28.7 usec per loop
$ python -V
Python 2.5.2
lst *= 0
has the same effect as
lst[:] = []
It's a little simpler and maybe easier to remember. Other than that there's not much to say
The efficiency seems to be about the same
list = []
will reset list to an empty list.
Note that you generally should not shadow reserved function names, such as list, which is the constructor for a list object -- you could use lst or list_ instead, for instance.
Another simple code you could use (depending on your situation) is:
index=len(list)-1
while index>=0:
del list[index]
index-=1
You have to start index at the length of the list and go backwards versus index at 0, forwards because that would end you up with index equal to the length of the list with it only being cut in half.
Also, be sure that the while line has a "greater than or equal to" sign. Omitting it will leave you with list[0] remaining.

how do i write this code (easy way), python problem?

I am very new in Python, and I am really surprised at the following line of code.
p, q = [int(x) for x in input().split()]
how to write basic??
You can make a loop instead to understand better, but the code won't work because the logic is false:
your_input = input().split()
list_ = []
for x in your_input:
list_.append(int(x))
p, q = list_
The .split() put the str in input in a list so you just have one element and one loop. But the p,q = at the end suggests it waits two elements in the list. So it can't work. Maybe you can delete the .split() if you want each digit of a number less than 100. Depends on the result you want.

make a function that take an integer and reduces it down to an odd number

I'm working on my final for a class I'm taking(Python 3) im stuck at this part.
he gave us a file with numbers inside of it. we opened it and add those numbers to a list.
"Create a function called makeOdd() that returns an integer value. This function should take in any integer and reduce it down to an odd number by dividing it in half until it becomes an odd number.
o For example 10 would be cut in half to 5.
o 9 is already odd, so it would stay 9.
o But 12 would be cut in half to 6, and then cut in half again to 3.
o While 16 would be cut to 8 which gets cut to 4 which gets cut to 2 which gets cut to 1.
 Apply this function to every number in the array. "
I have tried to search the internet but i have not clue where to even begin with this one. any help would be nice.
Here my whole final so far:
#imports needed to run this code.
from Final_Functions import *
#Defines empty list
myList = []
sumthing = 0
sortList = []
oddList = []
count = 0
#Starts the Final Project with my name,class, and quarter
intro()
print("***************************************************************",'\n')
#Opens the data file and reads it then places the intrager into a list we can use later.
with open('FinalData.Data', 'r') as f:
myList = [line.strip() for line in f]
print("File Read Complete",'\n')
#Finds the Sum and Adverage of this list from FinalData.Data
print("*******************sum and avg*********************************")
for oneLine in myList:
tempNum = int(oneLine)
sumthing = sumthing + tempNum
avg = sumthing /1111
print("The Sum of the List is:",sumthing)
print("The Adverage of the List is:",avg,'\n')
print("***************************************************************",'\n')
#finds and prints off the first Ten and the last ten numbers in the list
firstTen(myList)
lastTen(myList)
print("***************************************************************",'\n')
#Lest sort the list then find the first and last ten numbers in this list
sortList = myList
sortList.sort()
firstTen(sortList)
lastTen(sortList)
print("****************************************************************",'\n')
Language:Python 3
I don't want to give you the answer outright, so I'm going to talk you through the process and let you generate your own code.
You can't solve this problem in a single step. You need to divide repeatedly and check the value every time to see if it's odd.
Broadly speaking, when you need to repeat a process there are two ways to proceed; looping and recursion. (Ok, there are lots, but those are the most common)
When looping, you'd check if the current number x is odd. If not, halve it and check again. Once the loop has completed, x will be your result.
If using recursion, have a function that takes x. If it's odd, simply return x, otherwise call the function again, passing in x/2.
Either of those methods will solve your problem and both are fundamental concepts.
adding to what #Basic said, never do import * is a bad practice and is a potential source of problem later on...
looks like you are still confuse in this simple matter, you want to given a number X reduce it to a odd number by dividing it by 2, right? then ask yourself how I do this by hand? the answer is what #Basic said you first ask "X is a even number?" if the answer is No then I and done reducing this number, but if the answer is Yes then the next step dividing it by 2 and save the result in X, then repeat this process until you get to the desire result. Hint: use a while
to answer your question about
for num in myList:
if num != 0:
num = float(num)
num / 2
the problem here is that you don't save the result of the division, to do that is as simple as this
for num in myList:
if num != 0:
num = float(num)
num = num / 2

Switching positions of two strings within a list

I have another question that I'd like input on, of course no direct answers just something to point me in the right direction!
I have a string of numbers ex. 1234567890 and I want 1 & 0 to change places (0 and 9) and for '2345' & '6789' to change places. For a final result of '0678923451'.
First things I did was convert the string into a list with:
ex. original = '1234567890'
original = list(original)
original = ['0', '1', '2' etc....]
Now, I get you need to pull the first and last out, so I assigned
x = original[0]
and
y = original[9]
So: x, y = y, x (which gets me the result I'm looking for)
But how do I input that back into the original list?
Thanks!
The fact that you 'pulled' the data from the list in variables x and y doesn't help at all, since those variables have no connection anymore with the items from the list. But why don't you swap them directly:
original[0], original[9] = original[9], original[0]
You can use the slicing operator in a similar manner to swap the inner parts of the list.
But, there is no need to create a list from the original string. Instead, you can use the slicing operator to achieve the result you want. Note that you cannot swap the string elements as you did with lists, since in Python strings are immutable. However, you can do the following:
>>> a = "1234567890"
>>> a[9] + a[5:9] + a[1:5] + a[0]
'0678923451'
>>>

Resources