MDd
MDd

Reputation: 35

Python: 'For'loop only runs once, Project Euler

I've been learning Python and playing with Project Euler to recondition some of my math skills. I ran into an issue with Problem 35. I've generated all Primes under 1 million, eliminated those containing any even numbers, and am now just trying to run the last check with the remaining ~3k primes.

This function is supposed to:

  1. Take a list of the ~3k primes.
  2. Return a new list composed of lists of all rotations for each item in the original list.

Here's what I have, with how I understand each line:

def rotations(lst):
    newlist = []
    for i in lst:                                              # Take each int item in list. 
        s = [int(j) for j in str(i)]                           # Turn each item into a list of digit strings
        num = ([s[k:]+s[:-len(s)+k] for k in range(len(s))])   # Generate list of rotations of strings 
        tmplst = [] 
        for l in num:                                          # For each string rotation
            tmplst.append(int(''.join(map(str,l))))            # Turn it into an integer, add that int to tmplst
        newlist.append(tmplst)                                 # Add each tmplist to 'newlist'
    return newlist

Inputting rotations([123,456]) only yields:

[[123, 231, 312]]

When I'm expecting

[[123, 231, 312],[456,564,645]]

Any clues to what might be going wrong?

Upvotes: 2

Views: 13050

Answers (2)

James Waldby - jwpat7
James Waldby - jwpat7

Reputation: 8711

The whitespace error mentioned in previous answer accounts for the immediate problem – returning a result at the end of the first pass of for i in lst:, instead of after the loop completes – but it also would make sense to simplify your code so there is less of it and errors are easier to spot. Here is an example (with function renamed from rotations to rotor for distinction).

def rotor(lst):
    out = []
    for i in lst:
        s = str(i)
        out.append([int(s[k:]+s[:k]) for k in range(len(s))])
    return out

Given the above, rotor([456, 1789, 25887]) returns

[[456, 564, 645],
 [1789, 7891, 8917, 9178],
 [25887, 58872, 88725, 87258, 72588]]

Upvotes: 1

DSM
DSM

Reputation: 353209

Whenever someone has a code which other people (myself included) can't reproduce the strange behaviour of, I immediately think: whitespace error. And looking at your code:

'    def rotations(lst):'
'            newlist = []'
'            for i in lst:                                              # Take each int item in list. '
'            \t    s = [int(j) for j in str(i)]                           # Turn each item into a list of digit strings'
'            \t    num = ([s[k:]+s[:-len(s)+k] for k in range(len(s))])   # Generate list of rotations of strings '
'            \t    tmplst = [] '
'            \t    for l in num:                                          # For each string rotation'
"                \t        tmplst.append(int(''.join(map(str,l))))            # Turn it into an integer, add that int to tmplst"
"                \t    newlist.append(tmplst)                                 # Add each tmplist to 'newlist'"
'                    return newlist'
'        '

It looks to me like you might be mixing tabs and spaces. This can lead to very mysterious behaviour as certain lines aren't indented as much as you think they are. Run your program with

python -tt your_program_name.py

to confirm, and if so, switch to using four-space indentation (by which I mean "tabs" which consist of four spaces, not \t.)

Upvotes: 8

Related Questions