简体   繁体   中英

Tricky: How to compare Dictionary values (containing lists) with a list?

I am having a dict(containing lists) and a list, which I want to compare:

The first thing, I want to find out is whether each value-list (eg for issue1, the value-list is [1, 1, 0, 0, 0, 1, 1, 1] ) in ref has the same length as the list abf .

Then comes the tricky part: If they have the same length, I want to compare each item in the list abf with each item of the value-lists in ref .

But... Under one condition, the program shall move on to the next value-list in ref (without checking the remaining items of the current value-list), and this is if the item of the value-list is 1 and the corresponding item in the list abf is 0.

To make it clear, here is one example:

the value-list of the key 'issue1' in the dict ref is [1, 1, 0, 0, 0, 1, 1, 1]. The list abf is [1, 1, 0, 1, 0, 1, 0, 0] .

Now, I want to check each item of those two lists (the first item of the value-list of issue1 with the first item of the list abf , then the second item of issue1 with the second item of abf and so on...): As the first two items are 1 and 1 and the condition (see above) is not fulfilled, it shall go on to the next two items (which are again 1 and 1) and so on, UNTIL it gets to (in this case) the seventh items (which are 1 and 0). At this point it shall stop comparing value-list of issue1 with list abf and continue with comparing the next value-list (of issue2 ) with the list abf . I hope you get the idea!

Here is my code so far:

## ref is a dict with lists as values, abf is a list
ref = {'issue1': [1, 1, 0, 0, 0, 1, 1, 1], 
       'issue2': [1, 0, 0, 1, 0, 0, 0, 0], 
       'issue3': [0, 1, 0, 0, 1, 0, 0, 1]}
abf = [1, 1, 0, 1, 0, 1, 0, 0]

## getting the length of the lists in ref and abf ans save them in ref_total & abf_total
for key in ref:
    [int(item) for item in ref[key]]
ref_total = len(ref[key])
abf_total = len(abf)

## check whether ref_total and abf_total has same value
if ref_total == abf_total:
    for key, value in ref.items():
        for j in value:
            if (ref[key][j] == 1) and (abf[j] == 0): ## if item in ref is 1 and in abf is 0, go on to the next value-list
                break
            if j == abf_total-1: ## if he compared the whole value-list of the current key of ref with abf and the condition above did not occur, save the key of this value-list in resp!
                resp = ref[key]

else:
    resp = 'Length of strings varies!' ##if the lists don't have the same length

print resp ##let me know, which key "went through"

I am really looking forward to your responeses. The code does not work and I have no idea why!

There are few problems with your code, that I would like to point: -

for key in ref:
    [int(item) for item in ref[key]]

To start with, your above loop is ambiguous. Its not doing anything, but just creating a list which is then ignored

Secondly,

ref_total = len(ref[key])
abf_total = len(abf)

The above assignment does not work, because you have placed it outside the for loop. Indentation problem.

if ref_total == abf_total:
    for key, value in ref.items():

In the above code segment, rather than having your if condition first, and then the for loop, you should move your if condition in the for loop. So, for each key, value pair, check whether the len(value) == len(abf) . If true, then continue with the inner for loop.

if (ref[key][j] == 1) and (abf[j] == 0)

This condition does not account for abf[j] = 1 and ref[key][j] = 0 . Instead of checking the inequality, you can check the equality, and just take a negation of that. That would be easier. ( EDIT: - Just noticed that, you just want to check it for that condition only. So you can ignore this change).

Also, your inner loop should not be for j in value . You cannot index on j then. Use for j in range(ref_list) , to compare values at each index.


You can try out this code after the above changes: -

ref = {'issue1': [1, 1, 0, 0, 0, 1, 1, 1], 
       'issue2': [1, 0, 0, 1, 0, 0, 0, 0], 
       'issue3': [0, 1, 0, 0, 1, 0, 0, 1],
       'issue4': [1, 1, 0, 1, 0, 1, 0, 0]}
abf = [1, 1, 0, 1, 0, 1, 0, 0]
abf_total = len(abf)  # Since it will never change. Move it outside

for key, value in ref.items():
    resp = ""
    ref_total = len(value)        

    if ref_total == abf_total:
        for j in range(ref_total):

            if not (value[j] == abf[j]): 
                break
            if j == abf_total-1: 
                resp = value
                print resp

    else:
        resp = 'Length of strings varies!' ##if the lists don't have the same length

OUTPUT : -

[1, 1, 0, 1, 0, 1, 0, 0]

I have added some notes as comment, but this should work:

## ref is a dict with lists as values, abf is a list
ref = {'issue1': [1, 1, 0, 0, 0, 1, 0, 1],
       'issue2': [1, 0, 0, 1, 0, 0, 0, 0],
       'issue3': [0, 1, 0, 0, 1, 0, 0, 1]}
abf = [1, 1, 0, 1, 0, 1, 1, 0]

# abf_total does not change during cycle. Calculate it outside.
abf_total = len(abf)

## getting the length of the lists in ref and abf ans save them in ref_total & abf_total
for key, items in ref.iteritems():
    ref_total = len(items)

    ## check whether ref_total and abf_total has same value
    if ref_total == abf_total:
        # Here 'ref' screened the outside ref. Use 'i'
        for i, value in enumerate(items):
            if (items[i] == 1) and (abf[i] == 0): ## if item in ref is 1 and in abf is 0, go on to the next value-list
                break
        if i == abf_total-1:
            # if he compared the whole value-list of the current key of ref with abf and the condition above did not occur, save the key of
this value-list in resp!
            resp = "%s = %s" % (key, items)
    else:
        resp = 'Length of strings varies!' ##if the lists don't have the same length

print resp ##let me know, which key "went through"

The output is:

issue2 = [1, 0, 0, 1, 0, 0, 0, 0]

If I understand your requirement right, Python has that functionality built in. You can do this.

ref = {'issue1': [1, 1, 0, 0, 0, 1, 0, 1], 
       'issue2': [1, 0, 0, 1, 0, 0, 0, 0], 
       'issue3': [0, 1, 0, 0, 1, 0, 0, 1]}

abf = [1, 1, 0, 1, 0, 1, 1, 0]

abf == abf
# OUT: True


def findinref(d, abf):
    for key, value in ref.items():
        if value == abf:
            return value
    return None

findinref(ref, abf)

findinref(ref, [1,1,0,0,0,1,0,1])
# OUT: [1, 1, 0, 0, 0, 1, 0, 1]

thank you all very very much, you are really awesome! I didn't expect that much feedback!! You really helped me a lot. I went for Rohit Jain's solution - thank you very much Rohit!! Here is the complete code (if there is space for improvements, don't hesitate to critizise me! any feedback is really appreciated!!)

ref = {'issue1': [1, 1, 0, 0, 0, 1, 1, 1], 
       'issue2': [1, 0, 0, 1, 0, 0, 0, 0], 
       'issue3': [0, 1, 0, 0, 1, 0, 0, 1]}
abf = [1, 1, 0, 1, 0, 1, 0, 0]

abf_total = len(abf)

for key, value in ref.items():
    ref_total = len(ref[key])   
    if ref_total == abf_total:
        i = -1
        for j in value:
            i += 1
            if (j == 1) and (abf[i] == 0):
                break
            if i == len(abf)-1:
                resp = key
    else:
        resp = 'Length of strings varies!'
print resp

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