我有两个列表顺序组合,用python的map和zip funcionality创建一个嵌套列表;但是,我希望用itertools重新创建它。
此外,我试图理解为什么当我插入两个列表时itertools.chain返回一个展平列表,但是当我添加一个嵌套列表时,它只返回嵌套列表。
对这两个问题的任何帮助将不胜感激。
from tkinter import *
global widgets # this list will contain widgets to be deleted
widgets = []
def square():
global widgets
for widget in widgets[:]:
widget.destroy()
widgets.remove(widget)
ment = IntVar()
def mhello():
mtext = ment.get()
mtext *= 2
mlabel2 = Label(mGui, text=mtext)
mlabel = Label(mGui, text="Square")
mbutton = Button(mGui, text= "Submit", command = mhello)
nEntry = Entry(mGui, textvariable=ment)
widgets = widgets[:] + [mlabel, mbutton, nEntry] # destroy these later
for widget in widgets:
widget.pack() # pack them afterwards
def rectangle():
global widgets
for widget in widgets[:]:
widget.destroy()
widgets.remove(widget)
oneMent = IntVar()
twoMent = IntVar()
def mhello():
oneMtext = oneMent.get()
twoMtext = twoMent.get()
mtext = 0
mtext = oneMtext * twoMtext
mlabel2 = Label(mGui, text=mtext).pack()
mlabel = Label(mGui, text="Rectangle/Parallelogram")
mbutton = Button(mGui, text= "Submit", command = mhello)
oneEntry = Entry(mGui, textvariable=oneMent)
twoEntry = Entry(mGui, textvariable=twoMent)
widgets = widgets + [mlabel, mbutton, oneEntry, twoEntry] # destroy these later
for widget in widgets:
widget.pack() # pack them afterwards
def trapezium():
global widgets
for widget in widgets[:]:
widget.destroy()
widgets.remove(widget)
oneMent = IntVar()
twoMent = IntVar()
threeMent = IntVar()
def mhello():
oneMtext = oneMent.get()
twoMtext = twoMent.get()
threeMtext = threeMent.get()
mtext = 0
mtext = oneMtext + twoMtext
mtext /= 2
mtext *= threeMtext
mlabel2 = Label(mGui, text=mtext).pack()
mlabel = Label(mGui, text="Trapezium")
mbutton = Button(mGui, text= "Submit", command = mhello)
oneEntry = Entry(mGui, textvariable=oneMent)
twoEntry = Entry(mGui, textvariable=twoMent)
threeEntry = Entry(mGui, textvariable=threeMent)
widgets = widgets + [mlabel, mbutton, oneEntry, twoEntry, threeEntry] # destroy these later
for widget in widgets:
widget.pack() # pack them afterwards
def rhombus():
global widgets
for widget in widgets[:]:
widget.destroy()
widgets.remove(widget)
oneMent = IntVar()
twoMent = IntVar()
def mhello():
oneMtext = oneMent.get()
twoMtext = twoMent.get()
mtext = 0
mtext = oneMtext * twoMtext
mtext /= 2
mlabel2 = Label(mGui, text=mtext).pack()
mlabel = Label(mGui, text="Rhombus")
mbutton = Button(mGui, text= "Submit", command = mhello)
oneEntry = Entry(mGui, textvariable=oneMent)
twoEntry = Entry(mGui, textvariable=twoMent)
widgets = widgets + [mlabel, mbutton, oneEntry, twoEntry] # destroy these later
for widget in widgets:
widget.pack() # pack them afterwards
def restart():
mGui.destroy()
mGui = Tk()
mGui.geometry("450x450+500+300")
mGui.title("Square Area Finder")
mHomeLabel = Label(mGui, text="Use the drop down menu to select the quadrilateral you want to find the area of.").pack()
menu = Menu(mGui)
mGui.config(menu=menu)
file =Menu(menu)
file.add_command(label="Square", command=square)
file.add_command(label="Rectangle/Parallelogram", command=rectangle)
file.add_command(label="Trapezium", command=trapezium)
file.add_command(label="Rhombus", command=rhombus)
file.add_separator()
file.add_command(label="Quit", command=restart)
menu.add_cascade(label="Options", menu=file)
mGui.mainloop()
答案 0 :(得分:2)
我会尽力回答你的问题。
首先,itertools.chain
不会像您认为的那样发挥作用。 chain
需要x
次迭代,并按顺序迭代它们。当您调用chain
时,它基本上(内部)将对象打包到列表中:
chain("ABC", "DEF") # Internally creates ["ABC", "DEF"]
在方法内部,它一次访问一个项目,并迭代它们:
for iter_item in arguments:
for item in iter_item:
yield item
因此,当您调用chain([[a,b],[c,d,e],[f,g]])
时,它会创建一个包含一个可迭代对象的列表:您作为参数传递的列表。所以现在它看起来像这样:
[ #outer
[ #inner
[a,b],
[c,d,e],
[f,g]
]
]
chain
因此迭代内部列表,并按顺序返回三个元素:[a,b]
,[c,d,e]
和[f,g]
。然后他们被{{1}}重新包装,给你最初的东西。
顺便提一下,有一种方法可以做你想做的事:list
。这是chain.from_iterable
的替代构造函数,它接受单个迭代(例如列表),并将元素拉出以进行迭代。所以不要这样:
chain
你明白了:
# chain(l)
[ #outer
[ #inner
[a,b],
[c,d,e],
[f,g]
]
]
这将迭代三个子列表,并按一个序列返回它们,因此# chain.from_iterable(l)
[
[a,b],
[c,d,e],
[f,g]
]
将返回list(chain.from_iterable(l))
。
至于你的第二个问题:虽然我不知道为什么[a,b,c,d,e,f,g]
是这个过程的必要条件,但你可以在Python 2.x中这样做:
itertools
但是,在3.x中,list(itertools.izip(x,y))
功能已被删除。仍有izip
,它会匹配尽可能多的对,并接受额外对的填充值:zip_longest
返回list(zip_longest([a,b,c],[d,e,f,g,h],fillvalue="N"))
,因为第二个列表比第一个更长。正常[(a,d),(b,e),(c,f),(N,g),(N,h)]
将采用最短的可迭代并切断其余部分。
换句话说,除非您想要zip
而不是zip_longest
,否则zip
没有内置的压缩方法。