1

I have a list of lists where each list is a string of list of int, as shown below

a = ['[11, -12, -14, 13]',
     '[8, 5, -14, 15, 13]',
     '[13, 24, -14]']

I need to find a list of common integers (intersection of lists), in this case output should be [13, -14], since they are common in all.

Is there a simple way to do this since the individual lists are str type, where I can avoid a first iteration to eval and then find set?

4
  • 2
    It depends on what the syntax of the string is. In your example, those look like python string literals and ast.literal_eval would turn it into a python list. You could then use collections.Counter to count them. Or maybe set depending on what you mean by "common integers". Commented Aug 8, 2022 at 15:35
  • 1
    I don't think there's a way that doesn't first involve parsing the strings. You can, and probably should, use ast.literal_eval rather than eval, but since there is no syntactical information associated with the strings, whatever solution will end up being essentially equivalent to using literal_eval. Commented Aug 8, 2022 at 15:36
  • By which I mean, you can write your own parsing code, but that doesn't seem simpler than just using the string parsing code that is already in the standard library. Commented Aug 8, 2022 at 15:38
  • 1
    @tdelaney by common integers I meant the intersection of the lists Commented Aug 8, 2022 at 15:38

3 Answers 3

3
  1. map() the ast.literal_eval() function over list b to safely evaluate your list of strings into a iterator of lists.
  2. Then map() the set() constructor to cast your lists to sets.
  3. Finally, use functools.reduce() with set.intersection() to find the intersection of your sets.
from functools import reduce
from ast import literal_eval

answer = reduce(set.intersection,    # 3
             map(set,                # 2
             map(literal_eval, a)))  # 1
Sign up to request clarification or add additional context in comments.

Comments

1

Not the prettiest way of solving it but it works! This will handle any number of lists in A.

a = ['[11, -12, -14, 13]',
     '[8, 5, -14, 15, 13]',
     '[13, 24, -14]']

b = []

## this block converts the strings into integers, after this b will be a, but integer lists
for ls in a:
    truncated_str = ls.replace("[", "").replace("]", "")
    my_list_of_strs = truncated_str.split(",")
    my_list_of_ints = []
    for num in my_list_of_strs:
        my_list_of_ints.append(int(num))
    
    b.append(my_list_of_ints)
    
## this functions finds commonalites
def in_all_lists(lists, value_to_check):
    
    for my_list in lists:
        if value_to_check not in my_list:
            return False
    return True

common_numbers = []


# checks to see if values are common
for lst in b:

    for value in lst:
        if value not in common_numbers and in_all_lists(b, value):
            common_numbers.append(value)
            
print(common_numbers)  # prints [-14, 13]

Comments

1

Via the json library:

import json

l = [set(json.loads(x)) for x in a]

list(l.pop().intersection(*l))
> [-14, 13]

Explanation

json.loads() converts the string representation of a list to an actual list. Subsequently, we call intersection() on the list of sets. In particular, it is called first on the last element of that list via pop(). Then, all sets are passed as arguments into the intersection() via unpacking with *l. (The fact that the last set technically entered twice won't matter for the output. It just streamlined the code).

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.