【发布时间】:2014-09-21 13:04:43
【问题描述】:
假设您要编写一个程序,要求用户输入 X 个数字并将它们存储在 A 中,然后输入 Y 个数字并将它们存储在 B 中
在你投票结束之前:是的,这个问题已经被问到了here、here、here、here 以及可能的其他地方,但我在这个问题中回复了每个建议的解决方案,解释了为什么它们'不是我要找的东西,所以如果你认为它是重复的,请在投票结束之前继续阅读。这是一个严肃的问题,请参阅最后一段,了解支持我在此处尝试实现的功能的一小部分语言。
A = []
B = []
# First possibilty : using while loops
# you need to have a counter
i = 0
while (i < X):
A.append(input())
# and increment it yourself
i+=1
# you need to reset it
i = 0
while (i < Y):
B.append(input())
# and increment it again
i+=1
所以基本上你需要重复某件事x次,然后再重复Y次,但是python只有while循环和for循环。 while 循环不是重复某件事 N 次,而是在某个条件为 True 时重复某件事,这就是为什么您必须使用计数器、初始化它、递增它并对其进行测试的原因。
第二种解决方案是使用 for 循环:
# No need to create a counter
for x in xrange(x):
A.append(input())
# No need to increment the counter
# no need to reset the counter
for x in xrange(Y):
B.append(input())
这好多了 :),但还是有一些令人讨厌的地方:当我不需要 x 时,为什么我还要提供“x”?在我的代码中,我不需要知道我在哪个循环迭代中,我只需要重复 N 次,那么为什么我必须创建一个计数器呢?没有办法完全摆脱柜台吗?想象一下你可以写这样的东西:
# No need to supply any variable !
repeat(x):
A.append(input())
repeat(Y):
B.append(input())
这样不是更优雅吗?这不会更准确地反映您对代码的潜在读者的意图吗?不幸的是,python 不够灵活,无法创建新的语言结构(更高级的语言允许这样做)。所以我仍然必须使用 for 或 while 来循环事物。考虑到这一限制,我如何尽可能接近上层代码?
这是我尝试过的
def repeat(limit):
if hasattr(repeat,"counter"):
repeat.counter += 1
return repeat.counter < limit
repeat.limit = limit
repeat.counters = 0
return limit > 0 and True
while repeat(x):
A.append(input())
while repeat(Y):
B.append(input())
此解决方案适用于简单循环,但显然不适用于嵌套循环。
我的问题是
你知道任何其他可能的实现,可以让我获得与重复相同的接口吗?
反驳建议的解决方案
建议的解决方案 1.1:使用 itertools.repeat
您必须将您的代码放在一个函数中,并以某种方式在 itertools.repeat 中调用该函数。它与上面的重复实现不同,您可以在任意缩进的代码块上使用它。
建议解决方案 1.2:在 for 循环中使用 itertools.repeat
import itertools
for _ in itertools.repeat(None, N):
do_something()
你还在写一个for循环,而for循环需要一个变量(你提供了_),这完全没有抓住重点,再看一遍:
while repeat(5):
do_x()
do_y()
do_z()
没有提供任何东西只是为了循环。这就是我想要实现的目标。
建议的解决方案 2:使用 itertools.count
1) 你已经成功了一半。是的,您无需手动增加计数器,但仍需要手动创建计数器。示例:
c = itertools.count(1,1) # You still need this line
while( c.next() < 7):
a = 1
b = 4
d = 59
print "haha"
# No need to increment anything, that's good.
# c.incr() or whatever that would be
您还需要将计数器重置为 0,如果您在其上使用 with 语句,我认为这可以隐藏在函数中,以便在 with 语句的每一端,计数器都会被重置。
建议的解决方案 3:使用 with 语句
我从未使用过它,但据我所见,它用于在另一个函数中扫描 try/catch 代码。你怎么能用它来重复事情呢?我很高兴学习如何使用我的第一个 with 语句 :)
建议的解决方案 4:使用迭代器/生成器、xrange、列表推导...
不,不,不……
如果你写: [X() for _ in xrange(4)]
你是: 1)为您不关心的值创建一个列表。 2) 提供一个计数器 (_)
如果你写:
for _ in xrange(4):
X()
见上文第 2) 点
如果你写:
def repeat(n):
i = 0
while i < n :
yield i < n
i+1
那你应该如何使用 repeat ?像这样 ? :
for x in repeat(5):
X()
然后参见上面的第 2) 点。另外,这基本上是 xrange,所以为什么不使用 xrange 来代替。
还有其他很酷的想法吗?
有些人问我来自什么语言,因为他们不熟悉这种 repeat(N) 语法。我的主要编程语言是 python,但我确信我已经在其他语言中看到过这种语法。访问我的书签和在线搜索表明以下语言具有这种很酷的语法:
Ruby
它只是称为时间而不是重复。
#!/usr/bin/env ruby
3.times do
puts "This will be printed 3 times"
end
print "Enter a number: "
num = gets.chomp.to_i
num.times do
puts "Ruby is great!"
end
Netlogo
pd repeat 36 [ fd 1 rt 10 ]
;; the turtle draws a circle
AppleScript
[applescript]
repeat 3 times
--commands to repeat
end repeat
[/applescript]
Verilog
1 module repeat_example();
2 reg [3:0] opcode;
3 reg [15:0] data;
4 reg temp;
5
6 always @ (opcode or data)
7 begin
8 if (opcode == 10) begin
9 // Perform rotate
10 repeat (8) begin
11 #1 temp = data[15];
12 data = data << 1;
13 data[0] = temp;
14 end
15 end
16 end
17 // Simple test code
18 initial begin
19 $display (" TEMP DATA");
20 $monitor (" %b %b ",temp, data);
21 #1 data = 18'hF0;
22 #1 opcode = 10;
23 #10 opcode = 0;
24 #1 $finish;
25 end
26
27 endmodule
Rebol
repeat count 50 [print rejoin ["This is loop #: " count]]
Forth
LABEL 10 0 DO something LOOP 将重复某事 10 次,您不必提供计数器(Forth 自动将其存储在特殊变量 I 中)。
: TEST 10 0 DO CR ." Hello " LOOP ;
Groovy
您可以编写 1.upTo(4){ code } 或 4.times{ code } 来执行代码 4 次。 Groovy 在循环方面非常出色,它有五六种方法(upTo、times、step、java for、groovy for、foreach 和 while)。
// Using int.upto(max).
0.upto(4, createResult)
assert '01234' == result
// Using int.times.
5.times(createResult)
assert '01234' == result
// Using int.step(to, increment).
0.step 5, 1, createResult
assert '01234' == result
【问题讨论】:
-
您尝试这样做有什么特别的原因吗?
-
如果你想要速度,用 C 来做,但请注意,你已经花更多的时间思考它而不是运行它。如果您想要优雅,请使用函数式语言。如果您想快速实用地做到这一点,那么您已经有了答案。在 Python 中。
-
-1。我真的看不出这个问题对除了你之外的任何人有什么价值,因为你基本上是在问“我怎样才能以一种满足我对‘优雅’的高度主观和任意定义的方式编写这段代码”
-
如果不改变 python 的循环结构,就永远不会有一种合理的方式来做你想做的事,至少不会以一种不会最终成为 1) 显着更多代码的方式,打败你的主要目标和2)明显不太清楚,再次打败你的目的。 python中的循环是围绕迭代的概念设计的。而且由于 python 的核心习惯之一是应该有一种且只有一种明显的做某事的方式,所以当你不关心迭代器的返回时,它们拒绝进行循环。
-
使用
_表示您不使用迭代变量,因为约定已决定。您需要“不创建计数器”是愚蠢的,当然总会有一个 some 级别的计数器。 Python 语法不适合隐藏它。
标签: python loops nested-loops repeat