Python - gap on exit sequence,error on comparing decimal - python

I enter with numbers out of sequence, subtract the repeated ones, maintaining the order, subtract[']"of list on exit (is there any more pythonic way for this?). I do not know where I'm going wrong, it fails to compare units of the dozen and a space appears on the output.
a = 1 1 4 4 4 8 8 2 14 14 11 11
expected exit b = 1 4 8 2 14 11
wrong output
b = 1 4 8 2
def repeated(s):
t = []
[t.append(item) for item in s if not t.count(item)]
return t
def remove(s,to_remove):
for x in to_remove:
s = s.replace(x, '')
return s
def main():
a = input('a = ')
print('b = ', (remove(str(repeated(a)), "['],")))
main()
exit()

more better use sets
a = set(input().split())
print(' '.join(a))
sets can be contains only unique values, and you don't need to remove values. All values will be unique by default.

Related

While loop is not producing multiplication table [duplicate]

This question already has answers here:
Python check for integer input
(3 answers)
Closed 2 years ago.
i = 0
d = input("Enter the no. you want ")
while i < 11 :
print(i * d)
i+= 1
It is supposed to give multiplication table of d but it gives the following result for eg. '3' instead
3
33
333
3333
33333
333333
3333333
33333333
333333333
3333333333
The input() returns a string not an int and if you multiply a string in Python with an integer num, then you will get a string repeated num times. For example,
s = "stack"
print(s * 3) # Returns "stackstackstack"
You need to use int() constructor to cast the input from str to int.
d = int(input("Enter the no. you want "))
Try this:
d = int(input("Enter the no. you want "))
for i in range(1,11):
print(i * d)
In the above code, I have replaced your while loop construct with for loop and range() to get sequence of numbers.
BONUS:
To print/display the table in a nice and better way, try the below code:
for i in range(1,11):
print("%d X %d = %d" % (d, i, i * d))
Outputs:
Enter the no. you want 2
2 X 1 = 2
2 X 2 = 4
2 X 3 = 6
2 X 4 = 8
2 X 5 = 10
2 X 6 = 12
2 X 7 = 14
2 X 8 = 16
2 X 9 = 18
2 X 10 = 20

Trouble in swapping and assignment min and max elements

IMPORTANT UPD AT THE END!
The existing code works not for all cases.
def myfunc(x):
a = [int(i) for i in x.split()]
a[a.index(min(a))], a[a.index(max(a))] = a[a.index(max(a))], a[a.index(min(a))]
a = [str(i) for i in a]
return ' '.join(a)
myfunc()
It works for 3 4 5 2 1 and don't work for 1 5 4 3 2.
Why?
!!!UPD: I made some changes and it looks very strange.
I used two different lines separately (with commented one of them). The program gives different results in some cases. BUT THE MOST INTERESTING, when I used two of them, uncommented - the program don't return the income string?
# a[a.index(min(a))], a[a.index(max(a))] = a[a.index(max(a))], a[a.index(min(a))]
a[a.index(max(a))], a[a.index(min(a))] = a[a.index(min(a))], a[a.index(max(a))]
Cases which I use:
#print(myfunc("5 1 4 3 2"))
#print(myfunc("1 5 4 3 2"))
#print(myfunc("3 4 5 2 1"))
#print(myfunc("-30000 30000"))
#print(myfunc("2147483647 -2147483648"))
#print(myfunc("1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 17 16 15 14"))
#print(myfunc("1 2 3 4 5 6 7 8 9 10"))
#print(myfunc("1 9 8 7 6 5 4 3 2 10"))
UPD+=1 Guys I changed code to:
minind = a.index(min(a))
maxind = a.index(max(a))
a[minind], a[maxind] = a[maxind], a[minind]
Now it works for all case. But question about previous cases are still open
Please help. I spend about 2 hours in tries to find some explanation of this...
Please help
The reason it doesn't work is because the assignments are being executed sequentially. When you write:
a[a.index(min(a))], a[a.index(max(a))] = a[a.index(max(a))], a[a.index(min(a))]
it's essentially equivalent to:
tempmax, tempmin = a[a.index(max(a))], a[a.index(min(a))]
a[a.index(min(a))] = tempmax
a[a.index(max(a))] = tempmin
But notice that after doing the tempmax assignment, a.index(max(a)) can change. index() returns the earliest index, so if the minimum element was before the maximum element, this will now return the original minimum element's location (because it now contains the maximum element), and assigns tempmin back to it.
Your code assumes that the indexes to be assigned are computed before any of the assignments are done, but that's not how it actually works.
Your code doesn't work if the minimum is located before the maximum.
For example:
s = "1 5 4 3 2" # this doesn't work
myfunc(s)
>>> '1 5 4 3 2'
s = "5 1 4 3 2" # this works
myfunc(s)
>>> '1 5 4 3 2'
But, as you noticed, if you define indices before swapping, everything works fine.
def myfunc(x):
a = [int(i) for i in x.split()]
mn = a.index(min(a))
mx = a.index(max(a))
a[mn], a[mx] = a[mx], a[mn]
a = [str(i) for i in a]
return ' '.join(a)
s = "1 5 4 3 2"
myfunc(s)
>>> '5 1 4 3 2'
I'm waiting for some illuminati mind to have an answer for this.

What's the cleanest way to print an equally-spaced list in python?

Please close if this is a duplicate, but this answer does not answer my question as I would like to print a list, not elements from a list.
For example, the below does not work:
mylist = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
print(%3s % mylist)
Desired output:
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
Basically, if all items in the list are n digits or less, equal spacing would give each item n+1 spots in the printout. Like setw in c++. Assume n is known.
If I have missed a similar SO question, feel free to vote to close.
You can exploit formatting as in the example below. If you really need the square braces then you will have to fiddle a bit
lst = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
frmt = "{:>3}"*len(lst)
print(frmt.format(*lst))
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
items=range(10)
''.join(f'{x:3}' for x in items)
' 0 1 2 3 4 5 6 7 8 9'
If none of the other answers work, try this code:
output = ''
space = ''
output += str(list[0])
for spacecount in range(spacing):
space += spacecharacter
for listnum in range(1, len(list)):
output += space
output += str(list[listnum])
print(output)
I think this is the best yet, as it allows you to manipulate list as you wish. even numerically.
mylist = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
print(*map(lambda x: str(x)+" ",a))

Formatting lists

I need to create a function that takes inputs of lists from the user and returns them as such:
>>> print_table([[0,1,2,3,4,5],[0,1,4,9,16,25],[0,1,8,27,64,125]])
0 1 2 3 4 5
0 1 4 9 16 25
0 1 8 27 64 125
>>> print_table(times_table(6,6))
0 0 0 0 0 0 0
0 1 2 3 4 5 6
0 2 4 6 8 10 12
0 3 6 9 12 15 18
0 4 8 12 16 20 24
0 5 10 15 20 25 30
0 6 12 18 24 30 36
The times_table refers to my current code:
def times_table(s):
n = int(input('Please enter a positive integer between 1 and 15: '))
for row in range(n+1):
s = ''
for col in range(n+1):
s += '{:3} '.format(row * col)
print(s)
Help me if you can....
To get two values as input from the user, i.e. number of columns and rows, you can do as follows:
in_values = input('Please enter two positive integers between 1 and 15, separated by comma (e.g. 2,3): ')
m,n = map(int, in_values.split(','))
print(m,n)
To print out a formatted list of lists, you may wish to consider using string formatting through the format() method of strings. One thing I notice in your upper example is that you only get to 3 digits, and the space between the numbers seems to be unchanging. For lists with large numbers, this will likely mess up the formatting of the table. By using the format() method, you can take this into account and keep your table nicely spaced.
The easiest way I can think of to accomplish this is to determine what is the single largest number (most digits) in the entire list of lists and then incorporate that in the formatting. I would recommend you read up on string formatting for the python type string (including the mini formatting language).
Assuming s is the argument passed in to print_table:
maxchars = len(str(max(max(s))))
This will provide the largest number of characters in a single entry in the list. You can then utilize this number in the formatting of the rows in a for loop:
for lst in l:
output = ""
for i in lst:
output += "{0:<{1}} ".format(i, maxchars)
print(output)
the line output += "{0:<{1}} ".format(i, maxchars) means to print the number ({0} maps to the i in the call to format) left adjusted (<) in a space of characters "maxchars" wide ({1} maps to maxchars in the call to format).
So given your list of lists above, it will print it as:
0 1 2 3 4 5
0 1 4 9 16 25
0 1 8 27 64 125
but if the numbers are much larger (or any of the numbers are much larger, such as the 125 being replaced with 125125, it will unfortunately look like this because it is padding each item with the appropriate number of character spaces to contain a number of 6 characters:
0 1 2 3 4 5
0 1 4 9 16 25
0 1 8 27 64 125125
The above example takes a variable number of characters into account, however you could also format the string using an integer by replacing the {1} with an integer and omitting the maxchars portion (including both setting it and it being passed to format) if that is sufficient.
output += "{0:<4} ".format(i)
Optionally, you could figure out how to determine the largest number in a given column and then just format that column appropriately, however I am not going to put that in this answer.

Grouping list of integers in a range into chunks

Given a set or a list (assume its ordered)
myset = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
I want to find out how many numbers appear in a range.
say my range is 10. Then given the list above, I have two sets of 10.
I want the function to return [10,10]
if my range was 15. Then I should get [15,5]
The range will change. Here is what I came up with
myRange = 10
start = 1
current = start
next = current + myRange
count = 0
setTotal = []
for i in myset:
if i >= current and i < next :
count = count + 1
print str(i)+" in "+str(len(setTotal)+1)
else:
current = current + myRange
next = myRange + current
if next >= myset[-1]:
next = myset[-1]
setTotal.append(count)
count = 0
print setTotal
Output
1 in 1
2 in 1
3 in 1
4 in 1
5 in 1
6 in 1
7 in 1
8 in 1
9 in 1
10 in 1
12 in 2
13 in 2
14 in 2
15 in 2
16 in 2
17 in 2
18 in 2
19 in 2
[10, 8]
notice 11 and 20 where skipped. I also played around with the condition and got wired results.
EDIT: Range defines a range that every value in the range should be counted into one chuck.
think of a range as from current value to currentvalue+range as one chunk.
EDIT:
Wanted output:
1 in 1
2 in 1
3 in 1
4 in 1
5 in 1
6 in 1
7 in 1
8 in 1
9 in 1
10 in 1
11 in 2
12 in 2
13 in 2
14 in 2
15 in 2
16 in 2
17 in 2
18 in 2
19 in 2
[10, 10]
With the right key function, thegroupbymethod in the itertoolsmodule makes doing this fairly simple:
from itertools import groupby
def ranger(values, range_size):
def keyfunc(n):
key = n/(range_size+1) + 1
print '{} in {}'.format(n, key)
return key
return [len(list(g)) for k, g in groupby(values, key=keyfunc)]
myset = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
print ranger(myset, 10)
print ranger(myset, 15)
You want to use simple division and the remainder; the divmod() function gives you both:
def chunks(lst, size):
count, remainder = divmod(len(lst), size)
return [size] * count + ([remainder] if remainder else [])
To create your desired output, then use the output of chunks():
lst = range(1, 21)
size = 10
start = 0
for count, chunk in enumerate(chunks(lst, size), 1):
for i in lst[start:start + chunk]:
print '{} in {}'.format(i, count)
start += chunk
count is the number of the current chunk (starting at 1; python uses 0-based indexing normally).
This prints:
1 in 1
2 in 1
3 in 1
4 in 1
5 in 1
6 in 1
7 in 1
8 in 1
9 in 1
10 in 1
11 in 2
12 in 2
13 in 2
14 in 2
15 in 2
16 in 2
17 in 2
18 in 2
19 in 2
20 in 2
If you don't care about what numbers are in a given chunk, you can calculate the size easily:
def chunk_sizes(lst, size):
complete = len(lst) // size # Number of `size`-sized chunks
partial = len(lst) % size # Last chunk
if partial: # Sometimes the last chunk is empty
return [size] * complete + [partial]
else:
return [size] * complete

Categories

Resources