简体   繁体   中英

Python: Replace elements of one list with those of another if condition is met

I have two lists one called src with each element in this format:

['SOURCE:  filename.dc : 1 : a/path/: description','...]

And one called base with each element in this format:

['BASE: 1: another/path','...]

I am trying to compare the base element's number (in this case it's 4) with the source element's number (in this case it's 1).

If they match then i want to replace the source element's number with the base element's path.

Right now i can split the source element's number with a for loop like this:

    for w in source_list:
      src_no=(map(lambda s: s.strip(), w.split(':'))[2])

And i can split the base element's path and number with a for loop like this:

        for r in basepaths:
          base_no=(map(lambda s: s.strip(), r.split(':'))[1])
          base_path=(map(lambda s: s.strip(), r.split(':'))[2])

I expect the new list to look like ( base on the example of the two elements above):

['SOURCE:  filename.dc : another/path : a/path/: description','...]

the src list is a large list with many elements, the base list is usually three or four elements long and is only used to translate into the new list.

So there is one large list that will be sequentially browsed and a shorter one. I would turn the short one into a mapping to find immediately for each item of the first list whether there is a match:

base = {}
for r in basepaths:
    base_no=(map(lambda s: s.strip(), r.split(':'))[1])
    base_path=(map(lambda s: s.strip(), r.split(':'))[2])
    base[base_no] = base_path
for w in enumerate source_list:
    src_no=(map(lambda s: s.strip(), w.split(':'))[2])
    if src_no in base:
        path = base[src_no]
        # stuff...

Something like this:

for i in range(len(source_list)):
    for b in basepaths:
        if source_list[i].split(":")[2].strip() == b.split(":")[1].strip():
            source_list[i] = ":".join(source_list[i].split(":")[:3] + [b.split(":")[2]] + source_list[i].split(":")[4:])

just get rid of the [] part of the splits:

src=(map(lambda s: s.strip(), w.split(':')))
base=(map(lambda s: s.strip(), r.split(':')))

>> src
>> ['SOURCE', 'filename.dc', '1', 'a/path/', 'description']

the base will similarly be a simple list now just replace the proper element:

src[2] = base[2]

then put the elements back together if necessary:

src = ' : '.join(src)
def separate(x, separator = ':'):
    return tuple(x.split(separator))

sourceList = map(separate, source)

baseDict = {}
for b in map(separate, base):
    baseDict[int(b[1])] = b[2]


def tryFind(number):
    try:
        return baseDict[number]
    except:
        return number


result = [(s[0], s[1], tryFind(int(s[2])), s[3]) for s in sourceList]

This worked for me, it's not the best, but a start

I hacked something together for you, which I think should do what you want:

base_list = ['BASE: 1: another/path']
base_dict = dict()

# First map the base numbers to the paths
for entry in base_list:
    n, p = map(lambda s: s.strip(), entry.split(':')[1:])
    base_dict[n] = p

source_list = ['SOURCE:  filename.dc : 1 : a/path/: description']

# Loop over all source entries and replace the number with the base path of the numbers match   
for i, entry in enumerate(source_list):
    n = entry.split(':')[2].strip()
    if n in base_dict:
        new_entry = entry.split(':')
        new_entry[2] = base_dict[n]
        source_list[i] = ':'.join(new_entry)

Be aware that this is a hacky solution, I think you should use regexp (look into the re module) to extract number and paths and when replacing the number.

This code also alters a list while iterating over it, which may not be the most pythonic thing to do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM