0

First off i am certain that such a basic thing has been asked before, but i could not find a post about it.

I have this piece of example data:

'192.168.244.213': ['8', '4', '3', '1', '6', '5', '3', '2', '6', '5'], 
'192.168.244.214': ['6', '8', '7', '6', '5', '4', '2', '7', '5', '5'], 
'192.168.244.215': ['4', '10', '0', '8', '7', '0', '4', '3', '2', '6'], 
'192.168.244.230': ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0']

And i want to print out every line (each line is one dictionary key-value pair) that has a list-value whose list contains any amount of items that is not 0 (in this case, every line except the 4th)

I just cant seem to figure out this seemingly simple thing - what i tried before was those two things:

for i in d.keys():
    if "0" not in d[i]:
        print(i, d[i])

This one shows only lists that do not contain 0 AT ALL - so the third line would not be shown, even though it contains non-0 values

for i in d.keys():
    for j in d[i]:
        if j is not "0":
            print(i, d[i])

This one DOES show me what i want, but as you can tell, it prints every result way too often - one print for every list value that is not 0.

3
  • The key is the IP? and the values are chars in a list? Commented Feb 18, 2019 at 15:25
  • the value is the list itself, so its IP:list Commented Feb 18, 2019 at 15:28
  • The problem is that if "0" not in d[i] checks if 0 is in the list at all, so obviously it would skip line 3 as well. Austin's answer seems correct to me. Commented Feb 18, 2019 at 15:29

7 Answers 7

2

You can simply iterate over like

def all_zero(arr):
    for i in arr:
        if i != 0:
            return False
    else:
        return True

You can call it on all the lists one by one.

Sign up to request clarification or add additional context in comments.

Comments

2

Use a dictionary-comprehension:

d = {'192.168.244.213': ['8', '4', '3', '1', '6', '5', '3', '2', '6', '5'],
     '192.168.244.214': ['6', '8', '7', '6', '5', '4', '2', '7', '5', '5'],
     '192.168.244.215': ['4', '10', '0', '8', '7', '0', '4', '3', '2', '6'],
     '192.168.244.230': ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0']}

result = {k: v for k, v in d.items() if not all(x == '0' for x in v)}

# {'192.168.244.213': ['8', '4', '3', '1', '6', '5', '3', '2', '6', '5'],
#  '192.168.244.214': ['6', '8', '7', '6', '5', '4', '2', '7', '5', '5'],
#  '192.168.244.215': ['4', '10', '0', '8', '7', '0', '4', '3', '2', '6']}

The above code generates a new dictionary which omits all items where values are all zeros.

Now that you have a dictionary, you can easily do an iteration like so:

for k, v in result.items():
    print(k, v)

1 Comment

looks good! as a small bonus, can you tell me how i would print out every key:value pair in a new line?
1

Your bug is basically just a missing break:

for i in d.keys():
    for j in d[i]:
        if j != "0":
            print(i, d[i])
            break

However, for conciseness I would recommend you check out the any() function, which does exactly what you want: Return true if any of the elements of the iterable are true (when cast to booleans).

Eg:

for i in d.keys():
    if any(j != "0" for j in d[i]):
        print(i, d[i])

(The j is not "0" generator is only necessary because you have string values. For an int array, any(d[i]) would work.)

Even more "Pythonic" would be removing the need for a dictionary lookup:

for i, d_i in d.items():
    if any(j != "0" for j in d_i):
        print(i, d_i)

3 Comments

You should avoid comparing strings with is not. Use !=.
Oh, thanks! I didnt use break before, i always had struggles with nested loops because of that!
About "is not": Thanks, the OP's code indeed has another potential bug there; I've now fixed this. (See also stackoverflow.com/questions/2988017/… on this topic.)
1

I like the other answers but I feel like you can get away with something like this as well:

for i in d.keys():
    #If there are as many zeroes as there are elements in the list...
    if d[i].count(0) == len(d[i]):
        #...You might as well skip it :)
        continue
    print(d[i])

2 Comments

This didnt work for me, it only prints the values and it doesnt filter out values that contain only 0s - it works when you count "0", because my lists didnt contain int 0 though, so thanks!
Ah, right, didn't notice you were using strings instead of ints. Should work with any char/value though as long as you replace the count to whatever you need.
1
for i in d.keys():
    all_zero = True
    for j in d[i]:
        if j is not "0":
            all_zero = False
            break
    if not all_zero:
        print(i, d[i])

This may work for almost every language :)

Comments

1

Have a look at how I could accomplish this.

d = {
    '192.168.244.213': ['8', '4', '3', '1', '6', '5', '3', '2', '6', '5'], 
    '192.168.244.214': ['6', '8', '7', '6', '5', '4', '2', '7', '5', '5'], 
    '192.168.244.215': ['4', '10', '0', '8', '7', '0', '4', '3', '2', '6'], 
    '192.168.244.230': ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0']
}

for key in d.keys():
    if all( item == '0' for item in d[key]):
        pass
    else:
        print(key, d[key])

Comments

0

You should use all in this case, consider following example:

digits = ['0', '2', '0', '4', '7', '5', '0', '3', '2', '6']
zeros = ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0']
print(all([k=='0' for k in digits])) #gives False
print(all([k=='0' for k in zeros])) #gives True

Please remember to deliver [k=='0' for k in ...] to all, as delivering list directly would give True for both digits and zeros, as both contain at least one non-empty str (str of length 1 or greater).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.