Tackling a few puzzle problems on a quiet Saturday night (wooohoo... not) and am struggling with sort(). The results aren't quite what I expect. The program iterates through every combination from 100 - 999 and checks if the product is a palindome. If it is, append to the list. I need the list sorted :D Here's my program:
list = [] #list of numbers
for x in xrange(100,1000): #loops for first value of combination
for y in xrange(x,1000): #and 2nd value
mult = x*y
reversed = str(mult)[::-1] #reverses the number
if (reversed == str(mult)):
list.append(reversed)
list.sort()
print list[:10]
which nets:
['101101', '10201', '102201', '102201', '105501', '105501', '106601', '108801',
'108801', '110011']
Clearly index 0 is larger then 1. Any idea what's going on? I have a feeling it's got something to do with trailing/leading zeroes, but I had a quick look and I can't see the problem.
Bonus points if you know where the puzzle comes from :P
You are sorting strings, not numbers. '101101' < '10201' because '1' < '2'. Change list.append(reversed) to list.append(int(reversed)) and it will work (or use a different sorting function).
Sort is doing its job. If you intended to store integers in the list, take Lukáš advice. You can also tell sort how to sort, for example by making ints:
list.sort(key=int)
the key parameter takes a function that calculates an item to take the list object's place in all comparisons. An integer will compare numerically as you expect.
(By the way, list is a really bad variable name, as you override the builtin list() type!)
Your list contains strings so it is sorting them alphabetically - try converting the list to integers and then do the sort.
You're sorting strings, not numbers. Strings compare left-to-right.
No need to convert to int. mult already is an int and as you have checked it is a palindrome it will look the same as reversed, so just:
list.append(mult)
You have your numbers stored as strings, so python is sorting them accordingly. So: '101x' comes before '102x' (the same way that 'abcd' will come before 'az').
No, it is sorting properly, just that it is sorting lexographically and you want numeric sorting... so remove the "str()"
The comparator operator is treating your input as strings instead of integers. In string comparsion 2 as the 3rd letter is lexically greater than 1.
reversed = str(mult)[::-1]
Related
I need to find a way to split a string of multiples numbers into multiples strings of those numbers and then split again to have individual digits which would allow me to test those first inputed numbers to see if they are a harshad number without using for, else, while and if.
So far i'm able to split the input string:
a = input("Multiple numbers separated by a ,: ")
a.split(",")
Then I need to split again I think I need to use the map function. Any idea how to go any further.
The python builtin functions map, filter, and reduce are going to be your friend when you are working in a more functional style.
map
The map function lets you transform each item in an iterable (list, tuple, etc.) by passing it to a function and using the return value as a new value in a new iteratable*.
The non-functional approach would use a for ... in construct:
numbers_as_strings = ["1", "12", "13"]
numbers_as_ints = []
for number in numbers_as_strings:
numbers_as_ints.append(int(number))
or more concisely a list comprehension
numbers_as_ints =[int(number) for number in numbers_as_strings]
Since you are eschewing for there is another way
numbers_as_ints = map(int, numbers_as_strings)
But you don't just want your strings mapped to integers, you want to test them for harshadiness. Since we're doing the functional thing let's create a function to do this for us.
def is_harshad(number_as_string):
return # do your harshad test here
Then you can map your numbers through this function
list(map(is_harshad, numbers_as_string)) # wrap in list() to resolve the returned map object.
>>> [True, True, False]
But maybe you want the results as a sequence of harshady number strings? Well check out filter
filter
The filter function lets you choose which items from an iterable you want to keep in a new iterable. You give it a function that operates on an single item and returns True for a keeper or False for a rejection. You also give it an iterable of items to test.
A non-functional way to do this is with a for loop
harshady_numbers = []
for number in numbers_as_strings:
if is_harshad(number):
harshady_numbers.append(number)
Or more concisely and nicely, with a list comprehension
harshady_numbers = [number for number in numbers_as_strings if is_harshady(number)]
But, since we're getting functional well use filter
harshady_numbers = filter(is_harshady, numbers_as_strings)
That's about it. Apply the same functional thinking to complete the is_harshad function and you're done.
map() can take more than one iterable argument and it returns an iterator not a list.
The question is
Write a program to sort a string without using built in method.
Input: "a390testai"
output: "039aaiest"
I have looked at some forums to find answer for this. I found this forum In Python, how can I naturally sort a list of alphanumeric strings such that alpha characters sort ahead of numeric characters? but it does not look like any of the solutions were using selection or bubble sort. My questions are:
1) When dealing with such a problem do I have to 1st convert the string to a list? For example: str=list("exam123ple") ? To avoid "TypeError: 'str' object does not support item assignment"
2) I tried using selection sort and bubble sort but they are not returning intended result.
#Selection sort
s="a390testai"
s=list(s) # convert to list
for i in range(len(s)):
min_val=min(s[i:])
min_val_pos=s.index(min_val)
s[i],s[min_val_pos]=s[min_val_pos],s[i]
print('s',s)
#Bubble sort
bs="a390testai"
bs=list(bs)
for i in range(0,len(bs)-1):
if bs[i]>bs[i+1]:
bs[i], bs[i+1]=bs[i+1],bs[i]
print(bs)
039testaai >> selection sort
390aestait >> bubble sort
Thanks in advance for your help and explanation.
Bubble sort needs more than one pass. Each time through, you go through one less element, since the last one has "bubbled" into place.
In your selection sort, s.index returns the index of the first matching item. So if your string has duplicate letters it returns the wrong one. You need to search inside the [i:] range and add i, to find the right instance.
Yes, you have to use list as strings are immutable and you can't change parts of them. Here is an example of bubble sort.
s = list('a390testai')
is_sorted = False
while not is_sorted:
for i in range(len(s)-1):
if s[i] > s[i+1]:
s[i+1], s[i] = s[i], s[i+1]
break
else:
is_sorted=True
print("".join(s))
I have the following list that I'd like to sort:
['104.900209904', '238.501860857', '9.59893298149', '362.470027924', '419.737339973']
I used the "sorted" function to do it:
Block1_Video1 = sorted(Block1_Video1)
However, this is what I get:
['104.900209904', '238.501860857', '362.470027924', '419.737339973', '9.59893298149']
Whereas this is what I want (a list sorted numerically, taking decimal points into account):
[''9.59893298149', 104.900209904', '238.501860857', '362.470027924', '419.737339973']
How can I accomplish this?
The sorting needs to be based on the float values of the corresponding strings in the list.
Block1_Video1 = ['104.900209904', '238.501860857', '9.59893298149', '362.470027924', '419.737339973']
sorted(Block1_Video1,key=lambda x:float(x))
Or simply use
sorted(Block1_Video1, key=float)
You have to convert your strings in numbers first, this is possible with the key-Argument of the sorted function:
Block1_Video1 = sorted(Block1_Video1, key=float)
or as you assign the new list to the same variable, you can also sort in-place:
Block1_Video1.sort(key=float)
I've been trying every iteration of a list comprehension that I can in the context.
I am getting a call from a database, converting it to a list of [['item', long integer]].
I want to convert the long integer to a regular one, because the rest of my math is in regular integrals.
I'm trying this:
catnum = c.fetchall()
catnum = [list(x) for x in catnum]
for x in catnum:
[int(y) for y in x]
I've also tried x[1], and a few other things (it is always in position 1 inside the list)
No luck. How do I convert only the second value in the list to a regular integer?
does this work?
catnum=[[x,int(y)] for x,y in catnum]
But, I think it's worth asking why you need to do this conversion. Python should handle long integers just fine anywhere a regular integer would work. There's a slight performance penalty to leaving them as long ints, but in most cases I don't think that would justify the extra work to convert to regular integers.
EDIT for the people reading the comments, my first answer was incorrect and did not involve a list comprehension. It relied on mutating the elements in catnum, but since those elements are in tuples, they can't be mutated.
[[x[0],int(x[1])] for x in catnum]
This will return a list of lists, where the first entry in the name and the second is the value cast down to a normal integer.
Tackling a few puzzle problems on a quiet Saturday night (wooohoo... not) and am struggling with sort(). The results aren't quite what I expect. The program iterates through every combination from 100 - 999 and checks if the product is a palindome. If it is, append to the list. I need the list sorted :D Here's my program:
list = [] #list of numbers
for x in xrange(100,1000): #loops for first value of combination
for y in xrange(x,1000): #and 2nd value
mult = x*y
reversed = str(mult)[::-1] #reverses the number
if (reversed == str(mult)):
list.append(reversed)
list.sort()
print list[:10]
which nets:
['101101', '10201', '102201', '102201', '105501', '105501', '106601', '108801',
'108801', '110011']
Clearly index 0 is larger then 1. Any idea what's going on? I have a feeling it's got something to do with trailing/leading zeroes, but I had a quick look and I can't see the problem.
Bonus points if you know where the puzzle comes from :P
You are sorting strings, not numbers. '101101' < '10201' because '1' < '2'. Change list.append(reversed) to list.append(int(reversed)) and it will work (or use a different sorting function).
Sort is doing its job. If you intended to store integers in the list, take Lukáš advice. You can also tell sort how to sort, for example by making ints:
list.sort(key=int)
the key parameter takes a function that calculates an item to take the list object's place in all comparisons. An integer will compare numerically as you expect.
(By the way, list is a really bad variable name, as you override the builtin list() type!)
Your list contains strings so it is sorting them alphabetically - try converting the list to integers and then do the sort.
You're sorting strings, not numbers. Strings compare left-to-right.
No need to convert to int. mult already is an int and as you have checked it is a palindrome it will look the same as reversed, so just:
list.append(mult)
You have your numbers stored as strings, so python is sorting them accordingly. So: '101x' comes before '102x' (the same way that 'abcd' will come before 'az').
No, it is sorting properly, just that it is sorting lexographically and you want numeric sorting... so remove the "str()"
The comparator operator is treating your input as strings instead of integers. In string comparsion 2 as the 3rd letter is lexically greater than 1.
reversed = str(mult)[::-1]