문제

I am writing some code in Python that is almost working, but there is one thing I am unable to figure out.

I need to loop through 2 lists. I want to loop through until the first list is complete; whereas the second list should repeat itself until the first list is complete.

I want to input a list of databases and a list of streams. Then I want the code to output the 9 lines by replacing where it has "+ stream +" and "+ item +". The item part works fine, but I don't know how to output the list of streams while iterating through the list of databases. I want the streams to cycle through and then repeat. So it will start at 1a and then reach 3c, and then start over again at 1a. I want this to happen until it reaches the last database in the list.

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")

Here is the output:

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

My output has STREAM1a every time, but I want it to cycle through the pattern of 1a, 2a, 3a, 1b, 2b, 3b, 1c, 2c, and 3c. As mentioned, if I have more than 9 databases, then it would start over at 1a again. How can I achieve this?

The only part of my code that isn't working the way I want is where it says "+ stream +".

도움이 되었습니까?

해결책

You should use itertools.cycle. This will allow you to get the elements of a list in an endlessly repeating cycle. Add this code at the start of your loop:

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

or as @HughBothwell suggested, you can use zip and include it in the definition of the for loop:

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

Either way will give you the next stream at each iteration of the loop. If you have more dbs than streams, then it will repeat.

다른 팁

The trick is to use iterator from itertools called 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")

bonus - command line parameters parsing using docopt

Small bonus: to let you call the script and conveniently enter paremeters from command line

Install docopt package (just once)

$ pip install docopt

Write modifed version of the script 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")

Printout usage string:

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

Show some help string:

$ 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.

And call it for real use:

$ 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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top