2

I have the following list:

values = [
    ['registrationController', 'regBean', 'firstName'],
    ['registrationController', 'regBean', 'surname'],
    ['registrationController', 'regBean', 'userName'],
    ['registrationController', 'regBean', 'password'],
    ['registrationController', 'regBean', 'confirmPassword'],
    ['registrationController', 'regBean', 'emailAddress'],
    ['registrationController', 'regBean', 'confirmEmail'],
    ['registrationController', 'regBean', 'securityQuestionAndAnswerOne', 'question'],
    ['registrationController', 'regBean', 'securityQuestionAndAnswerOne', 'answer'],
    ['registrationController', 'regBean', 'securityQuestionAndAnswerTwo', 'question'],
    ['registrationController', 'regBean', 'securityQuestionAndAnswerTwo', 'answer'],
    ['registrationController', 'regBean', 'securityQuestionAndAnswerThree', 'question'],
    ['registrationController', 'regBean', 'securityQuestionAndAnswerThree', 'answer'],
    ['registrationController', 'regBean', 'tAndCAccepted']
]

I am trying to figure out how I can remove values that are preset in all off this lists and keep the values after a certain point when they become uniqe to get something like this:

unique_values = [
    ['firstName'],
    ['surname'],
    ['userName'],
    ['password'],
    ['confirmPassword'],
    ['emailAddress'],
    ['confirmEmail'],
    ['securityQuestionAndAnswerOne', 'question'],
    ['securityQuestionAndAnswerOne', 'answer'],
    ['securityQuestionAndAnswerTwo', 'question'],
    ['securityQuestionAndAnswerTwo', 'answer'],
    ['securityQuestionAndAnswerThree', 'question'],
    ['securityQuestionAndAnswerThree', 'answer'],
    ['tAndCAccepted']
]

Any ideas how I could achive this? I had tried various ways but can't really get close to a working solution.

2
  • Do the resulting lists still need to be in order? Commented Oct 31, 2018 at 14:34
  • Yes, ideally as I need to map the values back to the original list they came from. Commented Oct 31, 2018 at 14:36

5 Answers 5

4

Use set intersection to get all the common elements and a nested list comprehension to build the cleaned list:

common = set(values[0])
for lst in values[1:]:
    common = common.intersection(lst)

unique_values = [[v for v in lst if v not in common] for lst in values]
Sign up to request clarification or add additional context in comments.

Comments

2

Here's an easy to understand and readable version. It will preserve order as well.

common = set.intersection(*values)
reduced_values = [[value for value in l if value not in common] for l in values]

1 Comment

I see @schobaselgg has already answered with pretty much the same code down to the variable names. But in my defence, I hadn't seen his answer when I posted mine.
1

With a list comprehension:

>>> [
    [elt for elt in line if not all(elt in subline for subline in values)]
    for line in values
]

[['firstName'], ['surname'], ['userName'], ['password'], ['confirmPassword'], ['emailAddress'], ['confirmEmail'], ['securityQuestionAndAnswerOne', 'question'], ['securityQuestionAndAnswerOne', 'answer'], ['securityQuestionAndAnswerTwo', 'question'], ['securityQuestionAndAnswerTwo', 'answer'], ['securityQuestionAndAnswerThree', 'question'], ['securityQuestionAndAnswerThree', 'answer'], ['tAndCAccepted']]

Comments

-1

Assuming each value is unique within a list you could do something like this:

from collections import Counter
from itertools import chain

values = [
    ['registrationController', 'regBean', 'firstName'],
    ['registrationController', 'regBean', 'surname'],
    ['registrationController', 'regBean', 'userName'],
    ['registrationController', 'regBean', 'password'],
    ['registrationController', 'regBean', 'confirmPassword'],
    ['registrationController', 'regBean', 'emailAddress'],
    ['registrationController', 'regBean', 'confirmEmail'],
    ['registrationController', 'regBean', 'securityQuestionAndAnswerOne', 'question'],
    ['registrationController', 'regBean', 'securityQuestionAndAnswerOne', 'answer'],
    ['registrationController', 'regBean', 'securityQuestionAndAnswerTwo', 'question'],
    ['registrationController', 'regBean', 'securityQuestionAndAnswerTwo', 'answer'],
    ['registrationController', 'regBean', 'securityQuestionAndAnswerThree', 'question'],
    ['registrationController', 'regBean', 'securityQuestionAndAnswerThree', 'answer'],
    ['registrationController', 'regBean', 'tAndCAccepted']
]

counts = Counter(chain.from_iterable(values))
result = [[e for e in value if counts[e] != len(values)] for value in values]

print(result)

Output

[['firstName'], ['surname'], ['userName'], ['password'], ['confirmPassword'], ['emailAddress'], ['confirmEmail'], ['securityQuestionAndAnswerOne', 'question'], ['securityQuestionAndAnswerOne', 'answer'], ['securityQuestionAndAnswerTwo', 'question'], ['securityQuestionAndAnswerTwo', 'answer'], ['securityQuestionAndAnswerThree', 'question'], ['securityQuestionAndAnswerThree', 'answer'], ['tAndCAccepted']]

The idea is to count each element across values and get those that do not appear in all the elements of values:

3 Comments

The question states removing values common to all, not the first two. Maybe that's what he really wants, though.
Forgot to mention the nested list can be bigger and will not always have a fixed length like the example. picking them out using a slice would work this time but the position where the slice occurs in not guaranteed.
@SilverSlash Updated the answer, now it removes the elements common to all list.
-3
trunc_lists = [tuple(sublist[2:]) for sublist in values]
ans = [list(i) for i in set(trunc_lists)]

Note that the output is un-ordered

3 Comments

What is the "Note"?
Welcome to Stack Overflow! Thank you for the code snippet, which might provide some limited, immediate help. A proper explanation would greatly improve its long-term value by describing why this is a good solution to the problem, and would make it more useful to future readers with other similar questions. Please edit your answer to add some explanation, including the assumptions you've made.
It is a typo. I intended to note that the solution would output an un-ordered result

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.