Python遍历两个列表

1 投票
2 回答
1097 浏览
提问于 2025-04-18 05:55

我正在用Python写一些代码,基本上快完成了,但有一件事我搞不明白。

我需要遍历两个列表。我想先遍历第一个列表,直到它完成;而第二个列表应该在第一个列表完成之前不断重复。

我想输入一个数据库列表和一个流的列表。然后我希望代码输出9行内容,把"+ stream +"和"+ item +"的部分替换掉。item的部分工作得很好,但我不知道在遍历数据库列表时,如何输出流的列表。我希望流能够循环,然后再重复。所以它会从1a开始,然后到3c,再从1a开始。这个过程要一直进行,直到遍历完数据库列表中的最后一个数据库。

databases=input("Enter databases: ")
streams="1a 2a 3a 1b 2b 3b 1c 2c 3c"
stream="1a"

db_list = databases.split()
streams_list= streams.split()

for item in db_list:
    print("unlink $ORACLE_BASE/admin/" + item + "/backup")
    print("unlink $ORACLE_BASE/admin/" + item + "/dpdump")
    print("unlink $ORACLE_BASE/admin/" + item + "/exp")
    print("mkdir -p /oradba/app/oracle/acfsmounts/global/STREAM" + stream + "/" + item + "/backup")
    print("mkdir -p /oradba/app/oracle/acfsmounts/global/STREAM" + stream + "/" + item + "/dpdump")
    print("mkdir -p /oradba/app/oracle/acfsmounts/global/STREAM" + stream + "/" + item + "/exp")
    print("ln -s $ORACLE_BASE/acfsmounts/global/STREAM" + stream + "/" + item + "/backup $ORACLE_BASE/admin/" + item + "/backup")
    print("ln -s $ORACLE_BASE/acfsmounts/global/STREAM" + stream + "/" + item + "/dpdump $ORACLE_BASE/admin/" + item + "/dpdump")
    print("ln -s $ORACLE_BASE/acfsmounts/global/STREAM" + stream + "/" + item + "/exp    $ORACLE_BASE/admin/" + item + "/exp")

这是输出结果:

Enter databases: database1 database2 database3
unlink $ORACLE_BASE/admin/database1/backup
unlink $ORACLE_BASE/admin/database1/dpdump
unlink $ORACLE_BASE/admin/database1/exp
mkdir -p /oradba/app/oracle/acfsmounts/global/STREAM1a/database1/backup
mkdir -p /oradba/app/oracle/acfsmounts/global/STREAM1a/database1/dpdump
mkdir -p /oradba/app/oracle/acfsmounts/global/STREAM1a/database1/exp
ln -s $ORACLE_BASE/acfsmounts/global/STREAM1a/database1/backup $ORACLE_BASE/admin/database1/backup
ln -s $ORACLE_BASE/acfsmounts/global/STREAM1a/database1/dpdump $ORACLE_BASE/admin/database1/dpdump
ln -s $ORACLE_BASE/acfsmounts/global/STREAM1a/database1/exp    $ORACLE_BASE/admin/database1/exp
unlink $ORACLE_BASE/admin/database2/backup
unlink $ORACLE_BASE/admin/database2/dpdump
unlink $ORACLE_BASE/admin/database2/exp
mkdir -p /oradba/app/oracle/acfsmounts/global/STREAM1a/database2/backup
mkdir -p /oradba/app/oracle/acfsmounts/global/STREAM1a/database2/dpdump
mkdir -p /oradba/app/oracle/acfsmounts/global/STREAM1a/database2/exp
ln -s $ORACLE_BASE/acfsmounts/global/STREAM1a/database2/backup $ORACLE_BASE/admin/database2/backup
ln -s $ORACLE_BASE/acfsmounts/global/STREAM1a/database2/dpdump $ORACLE_BASE/admin/database2/dpdump
ln -s $ORACLE_BASE/acfsmounts/global/STREAM1a/database2/exp    $ORACLE_BASE/admin/database2/exp
unlink $ORACLE_BASE/admin/database3/backup
unlink $ORACLE_BASE/admin/database3/dpdump
unlink $ORACLE_BASE/admin/database3/exp
mkdir -p /oradba/app/oracle/acfsmounts/global/STREAM1a/database3/backup
mkdir -p /oradba/app/oracle/acfsmounts/global/STREAM1a/database3/dpdump
mkdir -p /oradba/app/oracle/acfsmounts/global/STREAM1a/database3/exp
ln -s $ORACLE_BASE/acfsmounts/global/STREAM1a/database3/backup $ORACLE_BASE/admin/database3/backup
ln -s $ORACLE_BASE/acfsmounts/global/STREAM1a/database3/dpdump $ORACLE_BASE/admin/database3/dpdump
ln -s $ORACLE_BASE/acfsmounts/global/STREAM1a/database3/exp    $ORACLE_BASE/admin/database3/exp

我的输出每次都是STREAM1a,但我希望它能按照1a、2a、3a、1b、2b、3b、1c、2c和3c的模式循环。如前所述,如果我有超过9个数据库,它就会再次从1a开始。我该怎么做才能实现这个呢?

我代码中唯一不按我想要的方式工作的部分就是"+ stream +"。

2 个回答

2

诀窍是使用来自 itertools 的一个叫 cycle 的迭代器。

from itertools import cycle
databases=input("Enter databases: ")
streams="1a 2a 3a 1b 2b 3b 1c 2c 3c"
stream="1a"

db_list = databases.split()
stream_list= streams.split()

for item, stream in zip(db_list, cycle(stream_list)):
    print("unlink $ORACLE_BASE/admin/" + item + "/backup")
    print("unlink $ORACLE_BASE/admin/" + item + "/dpdump")
    print("unlink $ORACLE_BASE/admin/" + item + "/exp")
    print("mkdir -p /oradba/app/oracle/acfsmounts/global/STREAM" + stream + "/" + item + "/backup")
    print("mkdir -p /oradba/app/oracle/acfsmounts/global/STREAM" + stream + "/" + item + "/dpdump")
    print("mkdir -p /oradba/app/oracle/acfsmounts/global/STREAM" + stream + "/" + item + "/exp")
    print("ln -s $ORACLE_BASE/acfsmounts/global/STREAM" + stream + "/" + item + "/backup $ORACLE_BASE/admin/" + item + "/backup")
    print("ln -s $ORACLE_BASE/acfsmounts/global/STREAM" + stream + "/" + item + "/dpdump $ORACLE_BASE/admin/" + item + "/dpdump")
    print("ln -s $ORACLE_BASE/acfsmounts/global/STREAM" + stream + "/" + item + "/exp    $ORACLE_BASE/admin/" + item + "/exp")

额外内容 - 使用 docopt 解析命令行参数

小额外提示:让你可以方便地从命令行调用脚本并输入参数。

安装 docopt 包(只需安装一次)。

$ pip install docopt

编写修改版的脚本 db.py

"""Usage:
    db.py -s <stream> (-s <stream>)... <db> <db>...
    db.py -h

For all database names <db> generates commands combining it with
names of <stream>s.
"""
from docopt import docopt
from itertools import cycle   

args = docopt(__doc__)

db_list = args["<db>"]
stream_list = args["<stream>"]

for item, stream in zip(db_list, cycle(stream_list)):
    print("unlink $ORACLE_BASE/admin/" + item + "/backup")
    print("unlink $ORACLE_BASE/admin/" + item + "/dpdump")
    print("unlink $ORACLE_BASE/admin/" + item + "/exp")
    print("mkdir -p /oradba/app/oracle/acfsmounts/global/STREAM" + stream + "/" + item + "/backup")
    print("mkdir -p /oradba/app/oracle/acfsmounts/global/STREAM" + stream + "/" + item + "/dpdump")
    print("mkdir -p /oradba/app/oracle/acfsmounts/global/STREAM" + stream + "/" + item + "/exp")
    print("ln -s $ORACLE_BASE/acfsmounts/global/STREAM" + stream + "/" + item + "/backup $ORACLE_BASE/admin/" + item + "/backup")
    print("ln -s $ORACLE_BASE/acfsmounts/global/STREAM" + stream + "/" + item + "/dpdump $ORACLE_BASE/admin/" + item + "/dpdump")
    print("ln -s $ORACLE_BASE/acfsmounts/global/STREAM" + stream + "/" + item + "/exp    $ORACLE_BASE/admin/" + item + "/exp")

打印出使用说明:

$ python db.py
Usage:
    db.py -s <stream> (-s <stream>)... <db> <db>...
    db.py -h

显示一些帮助信息:

$ python db.py -h
Usage:
    db.py -s <stream> (-s <stream>)... <db> <db>...
    db.py -h

For all database names <db> generates commands combining it with
names of <stream>s.

然后实际调用它:

$ python db.py -s s2 -s s2 db1 db2 db3
unlink $ORACLE_BASE/admin/db1/backup
unlink $ORACLE_BASE/admin/db1/dpdump
unlink $ORACLE_BASE/admin/db1/exp
mkdir -p /oradba/app/oracle/acfsmounts/global/STREAMs2/db1/backup
mkdir -p /oradba/app/oracle/acfsmounts/global/STREAMs2/db1/dpdump
mkdir -p /oradba/app/oracle/acfsmounts/global/STREAMs2/db1/exp
ln -s $ORACLE_BASE/acfsmounts/global/STREAMs2/db1/backup $ORACLE_BASE/admin/db1/backup
ln -s $ORACLE_BASE/acfsmounts/global/STREAMs2/db1/dpdump $ORACLE_BASE/admin/db1/dpdump
ln -s $ORACLE_BASE/acfsmounts/global/STREAMs2/db1/exp    $ORACLE_BASE/admin/db1/exp
unlink $ORACLE_BASE/admin/db2/backup
unlink $ORACLE_BASE/admin/db2/dpdump
unlink $ORACLE_BASE/admin/db2/exp
mkdir -p /oradba/app/oracle/acfsmounts/global/STREAMs2/db2/backup
mkdir -p /oradba/app/oracle/acfsmounts/global/STREAMs2/db2/dpdump
mkdir -p /oradba/app/oracle/acfsmounts/global/STREAMs2/db2/exp
ln -s $ORACLE_BASE/acfsmounts/global/STREAMs2/db2/backup $ORACLE_BASE/admin/db2/backup
ln -s $ORACLE_BASE/acfsmounts/global/STREAMs2/db2/dpdump $ORACLE_BASE/admin/db2/dpdump
ln -s $ORACLE_BASE/acfsmounts/global/STREAMs2/db2/exp    $ORACLE_BASE/admin/db2/exp
unlink $ORACLE_BASE/admin/db3/backup
unlink $ORACLE_BASE/admin/db3/dpdump
unlink $ORACLE_BASE/admin/db3/exp
mkdir -p /oradba/app/oracle/acfsmounts/global/STREAMs2/db3/backup
mkdir -p /oradba/app/oracle/acfsmounts/global/STREAMs2/db3/dpdump
mkdir -p /oradba/app/oracle/acfsmounts/global/STREAMs2/db3/exp
ln -s $ORACLE_BASE/acfsmounts/global/STREAMs2/db3/backup $ORACLE_BASE/admin/db3/backup
ln -s $ORACLE_BASE/acfsmounts/global/STREAMs2/db3/dpdump $ORACLE_BASE/admin/db3/dpdump
ln -s $ORACLE_BASE/acfsmounts/global/STREAMs2/db3/exp    $ORACLE_BASE/admin/db3/exp
3

你可以使用 itertools.cycle。这个工具可以让你不断循环地获取列表里的元素。你只需要在循环开始的地方加上这段代码:

stream_cycle = itertools.cycle(streams_list)
for item in db_list:
    stream = stream_cycle.next()

或者像 @HughBothwell 提到的,你也可以使用 zip,把它放在 for 循环的定义里:

for item, stream in zip(db_list, itertools.cycle(streams_list)):

无论哪种方式,每次循环都会给你下一个元素。如果你的数据库比流的数量多,那么它会重复使用这些流。

撰写回答