How to get a split up a list of numbers and insert into another list
目前我有一个文件,有6行数字,每行包含9个数字。关键是测试文件中每一行数字,如果它完成了一个魔方。例如,假设文件中的一行数字是4 3 8 9 5 1 2 7 6。前三个数字必须是矩阵中的第一行。接下来的三个数字需要是第二行,第三行也一样。因此,您需要得到一个矩阵:['4'、'3'、'8']、['9'、'5'、'1']、['2'、'7'、'6']
我需要测试这个矩阵,看看它是否是一个有效的魔方(行加15,列加15,对角线加15)。
我的代码当前为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | def readfile(fname): """Return a list of lines from the file""" f = open(fname, 'r') lines = f.read() lines = lines.split() f.close() return lines def assignValues(lines): magicSquare = [] rows = 3 columns = 3 for row in range(rows): magicSquare.append([0] * columns) for row in range(len(magicSquare)): for column in range(len(magicSquare[row])): magicSquare[row][column] = lines[column] return magicSquare def main(): lines = readfile(input_fname) matrix = assignValues(lines) print(matrix) |
每当我运行代码来测试它时,我都会得到:
1 | [['4', '3', '8'], ['4', '3', '8'], ['4', '3', '8']] |
所以你可以看到,我只是把前3个数放入我的矩阵中。最后,我的问题是,我将如何继续我的矩阵与以下6个数字行的数字?我不确定这是否是我在循环中可以做的事情,或者我的线路分裂错误,或者我完全走错了轨道?
谢谢。
要测试输入文件中的每一行是否包含幻方数据,您需要稍微重新组织代码。我用了一种不同的方法来填充矩阵。也许更难理解
我的代码为矩阵使用了一个元组列表,而不是一个列表列表,但是无论如何,元组在这里更适合,因为矩阵中的数据不需要修改。另外,我将
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #! /usr/bin/env python def make_square(seq, size): return zip(*[iter(seq)] * size) def main(): fname = 'mydata' size = 3 with open(fname, 'r') as f: for line in f: nums = [int(s) for s in line.split()] matrix = make_square(nums, size) print matrix #Now call the function to test if the data in matrix #really is a magic square. #test_square(matrix) if __name__ == '__main__': main() |
这里有一个修改过的
1 2 3 | def make_square(seq, size): square = zip(*[iter(seq)] * size) return [list(t) for t in square] |
我想我应该提到,实际上只有一个可能的3x 3魔方使用了从1到9的所有数字,不计算旋转和反射。但我想,对这一事实进行一次蛮力的演示是没有坏处的。:)
另外,我还有几年前(当我第一次学习Python时)编写的Python代码,它生成了大小为n x n的魔法方块(奇数n>=5)。如果你想看,请告诉我。
zip和迭代器对象下面是一些代码,简要说明了zip()和iter()函数的作用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | ''' Fun with zip ''' numbers = [1, 2, 3, 4, 5, 6] letters = ['a', 'b', 'c', 'd', 'e', 'f'] #Using zip to create a list of tuples containing pairs of elements of numbers & letters print zip(numbers, letters) #zip works on other iterable objects, including strings print zip(range(1, 7), 'abcdef') #zip can handle more than 2 iterables print zip('abc', 'def', 'ghi', 'jkl') #zip can be used in a for loop to process two (or more) iterables simultaneously for n, l in zip(numbers, letters): print n, l #Using zip in a list comprehension to make a list of lists print [[l, n] for n, l in zip(numbers, letters)] #zip stops if one of the iterables runs out of elements print [[n, l] for n, l in zip((1, 2), letters)] print [(n, l) for n, l in zip((3, 4), letters)] #Turning an iterable into an iterator object using the iter function iletters = iter(letters) #When we take some elements from an iterator object it remembers where it's up to #so when we take more elements from it, it continues from where it left off. print [[n, l] for n, l in zip((1, 2, 3), iletters)] print [(n, l) for n, l in zip((4, 5), iletters)] #This list will just contain a single tuple because there's only 1 element left in iletters print [(n, l) for n, l in zip((6, 7), iletters)] #Rebuild the iletters iterator object iletters = iter('abcdefghijkl') #See what happens when we zip multiple copies of the same iterator object. print zip(iletters, iletters, iletters) #It can be convenient to put multiple copies of an iterator object into a list iletters = iter('abcdefghijkl') gang = [iletters] * 3 #The gang consists of 3 references to the same iterator object print gang #We can pass each iterator in the gang to zip as a separate argument #by using the"splat" syntax print zip(*gang) #A more compact way of doing the same thing: print zip(* [iter('abcdefghijkl')]*3) |
下面是在交互式解释器中运行的相同代码,因此您可以轻松地看到每个语句的输出。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | >>> numbers = [1, 2, 3, 4, 5, 6] >>> letters = ['a', 'b', 'c', 'd', 'e', 'f'] >>> >>> #Using zip to create a list of tuples containing pairs of elements of numbers & letters ... print zip(numbers, letters) [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'), (6, 'f')] >>> >>> #zip works on other iterable objects, including strings ... print zip(range(1, 7), 'abcdef') [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'), (6, 'f')] >>> >>> #zip can handle more than 2 iterables ... print zip('abc', 'def', 'ghi', 'jkl') [('a', 'd', 'g', 'j'), ('b', 'e', 'h', 'k'), ('c', 'f', 'i', 'l')] >>> >>> #zip can be used in a for loop to process two (or more) iterables simultaneously ... for n, l in zip(numbers, letters): ... print n, l ... 1 a 2 b 3 c 4 d 5 e 6 f >>> #Using zip in a list comprehension to make a list of lists ... print [[l, n] for n, l in zip(numbers, letters)] [['a', 1], ['b', 2], ['c', 3], ['d', 4], ['e', 5], ['f', 6]] >>> >>> #zip stops if one of the iterables runs out of elements ... print [[n, l] for n, l in zip((1, 2), letters)] [[1, 'a'], [2, 'b']] >>> print [(n, l) for n, l in zip((3, 4), letters)] [(3, 'a'), (4, 'b')] >>> >>> #Turning an iterable into an iterator object using using the iter function ... iletters = iter(letters) >>> >>> #When we take some elements from an iterator object it remembers where it's up to ... #so when we take more elements from it, it continues from where it left off. ... print [[n, l] for n, l in zip((1, 2, 3), iletters)] [[1, 'a'], [2, 'b'], [3, 'c']] >>> print [(n, l) for n, l in zip((4, 5), iletters)] [(4, 'd'), (5, 'e')] >>> >>> #This list will just contain a single tuple because there's only 1 element left in iletters ... print [(n, l) for n, l in zip((6, 7), iletters)] [(6, 'f')] >>> >>> #Rebuild the iletters iterator object ... iletters = iter('abcdefghijkl') >>> >>> #See what happens when we zip multiple copies of the same iterator object. ... print zip(iletters, iletters, iletters) [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'h', 'i'), ('j', 'k', 'l')] >>> >>> #It can be convenient to put multiple copies of an iterator object into a list ... iletters = iter('abcdefghijkl') >>> gang = [iletters] * 3 >>> >>> #The gang consists of 3 references to the same iterator object ... print gang [<iterator object at 0xb737eb8c>, <iterator object at 0xb737eb8c>, <iterator object at 0xb737eb8c>] >>> >>> #We can pass each iterator in the gang to zip as a separate argument ... #by using the"splat" syntax ... print zip(*gang) [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'h', 'i'), ('j', 'k', 'l')] >>> >>> #A more compact way of doing the same thing: ... print zip(* [iter('abcdefghijkl')]*3) [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'h', 'i'), ('j', 'k', 'l')] >>> |
它只得到前3列总是因为
1 | magicSquare[row][column] = lines[column] |
因此
1 2 3 4 5 6 7 8 9 10 11 | def assignValues(lines): magicSquare = [] rows = 3 columns = 3 for row in range(rows): magicSquare.append([0] * columns) for line in range((sizeof(lines)/9)) #since the input is already split this means that the size of 'lines' divided by 9 is equal to the number of rows of numbers for row in range(len(magicSquare)): for column in range(len(magicSquare[row])): magicSquare[row][column] = lines[(9*line)+(3*row)+column] return magicSquare |
请注意,(3*行)+列将在每次迭代中向右移动3列而该(9*行)+(3*行)+列在每次迭代时都会向右移动9列(整行)
一旦你得到了这个,你现在就准备好去寻找魔方了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | def testMagicSquare(matrix): rows = 3 columns = 3 for a in len(matrix) test1 = 0 test2 = 0 test3 = 0 for b in range(3) if(sum(matrix[a][b])==15) test1=1 #flag true if whole row is 15 but turns false if a row is not 15 else test1=0 if((matrix[a][0][b]+matrix[a][1][b]+matrix[a][2][b])==15) test2=1 #flag true if column is 15 but turns false if a column is not 15 else test2=0 if(((matrix[a][0][0]+matrix[a][1][1]+matrix[a][2][2])==15) and ((matrix[a][0][2]+matrix[a][1][1]+matrix[a][2][0])==15)) test3=1 #flag true if diagonal is 15 but turns false if diagonal is not 15 else test3=0 if(test1>0 and test2>0 and test3>0) println('line ' + a + ' is a magic square') else println('line ' + a + ' is not a magic square') |