This code loads the data for Project Euler problem 18, but I feel that there must be a better way of writing it. Maybe with a double list comprehension, but I couldn't figure out how I might do that. It is a lot more difficult since the rows to split up are not uniform in length.
def organizeVar():
triangle = "\
75,\
95 64,\
17 47 82,\
18 35 87 10,\
20 04 82 47 65,\
19 01 23 75 03 34,\
88 02 77 73 07 63 67,\
99 65 04 28 06 16 70 92,\
41 41 26 56 83 40 80 70 33,\
41 48 72 33 47 32 37 16 94 29,\
53 71 44 65 25 43 91 52 97 51 14,\
70 11 33 28 77 73 17 78 39 68 17 57,\
91 71 52 38 17 14 91 43 58 50 27 29 48,\
63 66 04 68 89 53 67 30 73 16 69 87 40 31,\
04 62 98 27 23 09 70 98 73 93 38 53 60 04 23"
triangle = [row for row in list(triangle.split(","))]
adjTriangle = []
for row in range(len(triangle)):
adjTriangle.append([int(pos) for pos in triangle[row].split(" ")])
return adjTriangle
The code converts this string into a list of lists of int
s where the first list contains 75, the second list 95, 64, the third list 17, 47, 82, the fourth list 18, 35, 87, 10 and so on to the bottom row.
1 Answer 1
Avoid the need to escape the newlines by using Python's triple-quoted strings that can extend over multiple lines:
triangle = """ 75 95 64 17 47 82 18 35 87 10 20 04 82 47 65 19 01 23 75 03 34 88 02 77 73 07 63 67 99 65 04 28 06 16 70 92 41 41 26 56 83 40 80 70 33 41 48 72 33 47 32 37 16 94 29 53 71 44 65 25 43 91 52 97 51 14 70 11 33 28 77 73 17 78 39 68 17 57 91 71 52 38 17 14 91 43 58 50 27 29 48 63 66 04 68 89 53 67 30 73 16 69 87 40 31 04 62 98 27 23 09 70 98 73 93 38 53 60 04 23 """
Use the
strip
method to remove the whitespace at the beginning and end.Use the
splitlines
method to split the string into lines.Use the
split
method to split each line into words.Use the built-in
map
function to callint
on each word.
Putting that all together in a list comprehension:
>>> [map(int, line.split()) for line in triangle.strip().splitlines()]
[[75],
[95, 64],
[17, 47, 82],
[18, 35, 87, 10],
[20, 4, 82, 47, 65],
[19, 1, 23, 75, 3, 34],
[88, 2, 77, 73, 7, 63, 67],
[99, 65, 4, 28, 6, 16, 70, 92],
[41, 41, 26, 56, 83, 40, 80, 70, 33],
[41, 48, 72, 33, 47, 32, 37, 16, 94, 29],
[53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14],
[70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57],
[91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48],
[63, 66, 4, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31],
[4, 62, 98, 27, 23, 9, 70, 98, 73, 93, 38, 53, 60, 4, 23]]
In Python 3 map
doesn't return a list, so you have to write
[list(map(int, line.split())) for line in triangle.strip().splitlines()]
instead. If you prefer a double list comprehension you can write it like this:
[[int(word) for word in line.split()] for line in triangle.strip().splitlines()]
but the version with map
is shorter, and, I think, clearer.
-
\$\begingroup\$ Wow, that is awesome. :) \$\endgroup\$Jack J– Jack J2013年02月21日 12:51:38 +00:00Commented Feb 21, 2013 at 12:51
-
\$\begingroup\$ Using Python 3.3 I haven't quite gotten this to work. The closest I get while trying to use the map form is:
[line.strip().split(' ') for line in triangle.strip().splitlines()]
. This returns everything correctly except ints. When I try to use map, as inmap(int, line.strip().split(' ')
or even justmap(int, line.split())
I get a bunch of these:<map object at 0x0000000002F469E8>
. \$\endgroup\$Jack J– Jack J2013年02月21日 22:46:43 +00:00Commented Feb 21, 2013 at 22:46 -
\$\begingroup\$ See revised answer. (Also, it's usually better to write
.split()
instead of.split(" ")
unless you really want'a b'
to split into['a', '', 'b']
.) \$\endgroup\$Gareth Rees– Gareth Rees2013年02月21日 22:52:31 +00:00Commented Feb 21, 2013 at 22:52 -
\$\begingroup\$ I think also, if you try to put this into a function, you have to strip it twice; once for the two outside lines, and once for the indentation. If you don't, map will try to turn the extra space into ints, but will give an error when that happens... I didn't read your above comment in time. Alternatively I could just do that .split() to make it work. Thanks. \$\endgroup\$Jack J– Jack J2013年02月21日 23:03:15 +00:00Commented Feb 21, 2013 at 23:03
-
\$\begingroup\$ No, that's not necessary:
' a b '.split()
→['a', 'b']
\$\endgroup\$Gareth Rees– Gareth Rees2013年02月21日 23:07:03 +00:00Commented Feb 21, 2013 at 23:07
list()
thetrianle.split(",")
,split
will always return a list. \$\endgroup\$