Re: python challenge question (string manipulation)
John Salerno wrote: > It works, but is there a better way to shift the letters of the alphabet > for 'code'? I remember a method that did this for lists, I think, but I > can't remember what it was or if it worked for strings. Ah ha! This is cleaner: alphabet = string.ascii_lowercase code = string.ascii_lowercase[2:] + string.ascii_lowercase[:2] Yet it still seems kind of verbose. But since that's the official solution, I guess there's no other way to shift the characters in a string? -- http://mail.python.org/mailman/listinfo/python-list
Re: python challenge question (string manipulation)
John In python, strings are immutable - you have to create a new string no matter what you do. Also, I suspect you meant to say: >>> alphabet = string.ascii_lowercase >>> code = alphabet[2:] + alphabet[:2] I had a similar need recently for a guitar chord generator program I've been working on. Here is a "shift" function from my utilities module: def shift(list,num): '''Shifts sequence "list" by "num" places. if num is positive, list scrolls forwards, otherwise, backwards.''' if abs(num) > len(list): num=num%len(list) # Use mod to remove full list entry rotations newlist=list[-num:]+list[:-num] return newlist I actually create a new list here, although since lists are mutable, I could probably just change items in-place. There is very likely something already in the builtins or the standard library for this, but I just haven't searched hard enough. Interesting trap I kept falling into: calling a guitar string a "string" and then having collisions with the python type of the same name. Over and over again :) Regards Caleb -- http://mail.python.org/mailman/listinfo/python-list
Re: python challenge question (string manipulation)
Caleb Hattingh wrote: > Also, I suspect you meant to say: > alphabet = string.ascii_lowercase code = alphabet[2:] + alphabet[:2] Ah yes, I see what you did there. :) > I actually create a new list here, although since lists are mutable, I > could probably just change items in-place. There is very likely > something already in the builtins or the standard library for this, but > I just haven't searched hard enough. I'm pretty sure I read about a method for moving the items in lists around like that, so that you can shift the beginning to the end and vice versa. If I can find it, I'll let you know. -- http://mail.python.org/mailman/listinfo/python-list
Re: python challenge question (string manipulation)
Em Qua, 2006-03-29 às 19:34 +, John Salerno escreveu: > alphabet = string.ascii_lowercase > code = string.ascii_lowercase[2:] + string.ascii_lowercase[:2] > > Yet it still seems kind of verbose. But since that's the official > solution, I guess there's no other way to shift the characters in a string? --- from collections import deque from string import ascii_lowercase a = deque(ascii_lowercase) a.rotate(-2) print list(a) # prints ['c', 'd', ..., 'z', 'a', 'b'] --- But mind the performance! (as an exercise, time the performance of mine and your approach using the timeit module and post back to the list) HTH, -- Felipe. -- http://mail.python.org/mailman/listinfo/python-list
Re: python challenge question (string manipulation)
"John Salerno" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] > John Salerno wrote: > >> It works, but is there a better way to shift the letters of the alphabet >> for 'code'? I remember a method that did this for lists, I think, but I >> can't remember what it was or if it worked for strings. > > Ah ha! This is cleaner: > > alphabet = string.ascii_lowercase > code = string.ascii_lowercase[2:] + string.ascii_lowercase[:2] > > Yet it still seems kind of verbose. But since that's the official > solution, I guess there's no other way to shift the characters in a > string? The above would look less verbose if the second line 'paid attention' to the first and were written as the slightly more efficient code = alphabet[2:] + alphabet[:2] An alternative is shifted access. alphabet[(i+24)%26] Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: python challenge question (string manipulation)
Terry That is very succint. Rewriting my shift function given earlier: >>> import string >>> alpha = string.ascii_lowercase >>> print alpha abcdefghijklmnopqrstuvwxyz >>> def shift(lst, n): return [lst[(i+len(lst)-n)%len(lst)] for i,item in enumerate(lst)] >>> print shift(alpha,2) ['y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x'] Shorter and possibly as clear too; thanks! Keep well Caleb -- http://mail.python.org/mailman/listinfo/python-list
Re: python challenge question (string manipulation)
Em Qua, 2006-03-29 às 22:20 -0800, Caleb Hattingh escreveu: > That is very succint. Rewriting my shift function given earlier: > > >>> import string > >>> alpha = string.ascii_lowercase > >>> print alpha > abcdefghijklmnopqrstuvwxyz > >>> def shift(lst, n): > return [lst[(i+len(lst)-n)%len(lst)] for i,item in enumerate(lst)] It sure is short, but is it fast? Compare to the function below (the fastest I can think of ATM): def shift(lst, n): first = (-n) % len(lst) result = list(lst[first:]) # if lst is a iterable but not a list result.extend(lst[:first]) return result Now benchmarking: $ python2.4 -mtimeit -s "def shift(lst, n): return [lst[(i+len(lst)-n)% len(lst)] for i,item in enumerate(lst)]" "shift('abcdefghijklmnopqrstuvwxyz',2)" 1 loops, best of 3: 21.5 usec per loop $ python2.4 -mtimeit -s "def shift(lst, n): length = len(lst); first = (-n) % length; result = list(lst[first:]); result.extend(lst[:first]); return result" "shift('abcdefghijklmnopqrstuvwxyz',2)" 10 loops, best of 3: 3.98 usec per loop The five-line version is more than five times faster than the two-line counterpart. But it scales better too: $ python2.4 -mtimeit -s "string = 'abcdefghijklmnopqrstuvwxyz'*1 def shift(lst, n): length = len(lst); first = (-n) % length; result = list(lst[first:]); result.extend(lst[:first]); return result" "shift(string,2)" 100 loops, best of 3: 10.6 msec per loop $ python2.4 -mtimeit -s "string = 'abcdefghijklmnopqrstuvwxyz'*1 def shift(lst, n): return [lst[(i+len(lst)-n)%len(lst)] for i,item in enumerate(lst)]" "shift(string,2)" 10 loops, best of 3: 206 msec per loop With a 10 000 times larger list it takes almost 20 times less time. Of course a human can't perceive a 17.52 usec difference in time, but I'd like to make it clear that the two-line function shouldn't be used on a real system. What we learn from this? When it's not needed (like now), please don't iterate over all items of a list. HTH, -- Felipe. -- http://mail.python.org/mailman/listinfo/python-list
Re: python challenge question (string manipulation)
Felipe I get the same results as you. You make a good point about not iterating when it's not needed. I played around with your test code and found some interesting things: 1. enumerate vs. range(len()) has very little overhead (something I have wondered about) In my code, making the change causes the timing to go from 27.5 usec to 24.6 usec: basically nothing. 2. I combined the two result statements into one, and your code as written still appears consistently faster, albeit only slightly: One-line assignment to result: 6.98; 7.18; 6.49; 7.1 (code below) Your way via extend: 5.24; 5.26; 5.09; 5.3; 5.26; 5.21 (code further below) Is this because of "+" concatenation? My one-line assignment to result: [EMAIL PROTECTED] ~]$ python2.4 -mtimeit -s "def shift(lst, n): length = len(lst); first =(-n) % length; result = list(lst[first:]) + list(lst[:first]); return result" "shift('abcdefghijklmnopqrstuvwxyz',2)" 10 loops, best of 3: 6.98 usec per loop [EMAIL PROTECTED] ~]$ python2.4 -mtimeit -s "def shift(lst, n): length = len(lst); first =(-n) % length; result = list(lst[first:]) + list(lst[:first]); return result" "shift('abcdefghijklmnopqrstuvwxyz',2)" 10 loops, best of 3: 7.18 usec per loop [EMAIL PROTECTED] ~]$ python2.4 -mtimeit -s "def shift(lst, n): length = len(lst); first =(-n) % length; result = list(lst[first:]) + list(lst[:first]); return result" "shift('abcdefghijklmnopqrstuvwxyz',2)" 10 loops, best of 3: 6.49 usec per loop [EMAIL PROTECTED] ~]$ python2.4 -mtimeit -s "def shift(lst, n): length = len(lst); first =(-n) % length; result = list(lst[first:]) + list(lst[:first]); return result" "shift('abcdefghijklmnopqrstuvwxyz',2)" 10 loops, best of 3: 7.1 usec per loop Your code: [EMAIL PROTECTED] ~]$ python2.4 -mtimeit -s "def shift(lst, n): length = len(lst); first =(-n) % length; result = list(lst[first:]); result.extend(lst[:first]); return result" "shift('abcdefghijklmnopqrstuvwxyz',2)" 10 loops, best of 3: 5.24 usec per loop [EMAIL PROTECTED] ~]$ python2.4 -mtimeit -s "def shift(lst, n): length = len(lst); first =(-n) % length; result = list(lst[first:]); result.extend(lst[:first]); return result" "shift('abcdefghijklmnopqrstuvwxyz',2)" 10 loops, best of 3: 5.26 usec per loop [EMAIL PROTECTED] ~]$ python2.4 -mtimeit -s "def shift(lst, n): length = len(lst); first =(-n) % length; result = list(lst[first:]); result.extend(lst[:first]); return result" "shift('abcdefghijklmnopqrstuvwxyz',2)" 10 loops, best of 3: 5.09 usec per loop [EMAIL PROTECTED] ~]$ python2.4 -mtimeit -s "def shift(lst, n): length = len(lst); first =(-n) % length; result = list(lst[first:]); result.extend(lst[:first]); return result" "shift('abcdefghijklmnopqrstuvwxyz',2)" 10 loops, best of 3: 5.3 usec per loop [EMAIL PROTECTED] ~]$ python2.4 -mtimeit -s "def shift(lst, n): length = len(lst); first =(-n) % length; result = list(lst[first:]); result.extend(lst[:first]); return result" "shift('abcdefghijklmnopqrstuvwxyz',2)" 10 loops, best of 3: 5.26 usec per loop [EMAIL PROTECTED] ~]$ python2.4 -mtimeit -s "def shift(lst, n): length = len(lst); first =(-n) % length; result = list(lst[first:]); result.extend(lst[:first]); return result" "shift('abcdefghijklmnopqrstuvwxyz',2)" 10 loops, best of 3: 5.21 usec per loop Caleb -- http://mail.python.org/mailman/listinfo/python-list