0

Problem

I am trying to add() elements in a set at run time using a for loop:

    l1=set(map(int, input().split()))
    n=int(input())
    l2=set()
    for i in range(n):
        l2.add([int, input().split()])
    print(l1)
    print(l2)

Surprisingly, l1 is a set but, when I go on add() -ing elements to my set l2 in a loop I get :

TypeError: unhashable type: 'list'

Research Effort:

Here are other ways I have tried to add() elements to set l2 and failed :

l2=set()
for i in range(n):
    l2.add(map(int, input().split()))

The above prints out :

{<map object at 0x000001D5E88F36A0>, <map object at 0x000001D5E8C74AC8>}

Even this does not work!!

for i in range(n):
    l2.add(set(map(int, input().split())))

Please feel free to point out what I am doing wrong.

Basically, an answer will be helpful if one can explain how to add elements to a set data structure at runtime in a loop

Clarification:

I am looking for making a set of sets with user inputs at run time:

So if the user gives the following input:

1 2 3 4 5 6 7 8 9 10 11 12 23 45 84 78
2
1 2 3 4 5
100 11 12

The first line is my set l1. The second line is the number of sets and so since it is 2, the line afterwards are contents of the set.

Expected output:

{{1,2,3,4,5},{100,11,12}}
8
  • Try (int, tuple(input.split())). Mutable objects don't have hashcodes (since they would change when mutated and it would break how hash collections work). set is implemented using a hashtable so it can store only immutable stuff (or at least: stuff whose identity is immutable). lists are mutable hence don't have a hashcode. split also returns a list. Commented Jul 16, 2019 at 10:25
  • Sure, let me check and revert back. Commented Jul 16, 2019 at 10:26
  • I get : AttributeError: 'function' object has no attribute 'split' Commented Jul 16, 2019 at 10:27
  • Sorry input().split() the missing parenthesis were a typo Commented Jul 16, 2019 at 10:27
  • I wrote l2.add((int, tuple( input.split()))) Commented Jul 16, 2019 at 10:27

4 Answers 4

2

Since set.add only accepts as single element, not an iterable, you can loop over the map and add each element individually

l2 = set()
for i in range(n):
    for element in map(int, input().split()):
    l2.add(element)

This is not, in my opinion, as elegant as turning the map into a set as you did with l1, and adding it to the existing set:

l2 = set()
for i in range(n):
    l2 |= set(map(int, input().split()))

You can use set.update to avoid having to convert the map to a set explicitly:

l2 = set()
for i in range(n):
    l2.update(map(int, input().split()))

In fact, update can accept any number of iterables, so you can (but probably shouldn't) write a one-liner for the update:

l2 = set()
l2.update(*[map(int, input().split()) for i in range(n)])
Sign up to request clarification or add additional context in comments.

6 Comments

Your approach works well. But what I was looking for was perhaps if I could make it as a set of sets.
Like append n sets with runtime inputs in l2. { {....} , {...}, {....},....{...}}
I tried your edits and I am still not able to see it as a set of sets. Please feel free to address your confusions I am willing to help you with that.
@mishx. Show expected output in every part of the question.
I have added the expected output
|
1

Since l am now answering an essentially different question, I am posting a second answer.

A set is mutable, and therefore unhashable. Mutable objects can implement a hash function, but the built-in ones generally don't to avoid issues. Instead of using a set, use a hashable frozenset for your nested sets:

l2 = set()
for i in range(n):
    l2.add(frozenset(map(int, input().split())))

OR

l2 = {frozenset(map(int, input().split())) for i in range(n)}

OR

l2 = set(frozenset(map(int, input().split())) for i in range(n))

You won't be able to modify the sub-sets of l2, but they will behave as sets for at other purposes.

4 Comments

I'm trying it out. Will let you know in a sec
I'm not much familiar with frozenset() but my output shows as - {frozenset({1, 2, 3, 4, 5}), frozenset({11, 100, 12})}
It looks like each element is different to other and is a set.But not sure why the word frozenset written in them
@mishsx. Because when you print a built-in container, it prints the elements with repr. The repr of a frozenset is a string that should let you construct the object, and so contains the word frozenset.
0

Hopeful this helps you.

l1=set(map(int, input('Enter first set: ').split()))
print(l1)
n=int(input('Enter n: '))
l2=set()
for i in range(n):
    l2 = l2 | set(map(int, input(f'Enter {i+2}rd set: ').split()))

print(l2)
# {1,2,3,4,5,100,11,12}
  • In python you cannot have set of lists

  • Use merge operator instead of add

  • The {{1,2,3,4,5},{100,11,12}} expression is both mathematically and programming wrong.

  • Mathematically set of sets is intersection of sets.

  • You can have list of sets but no sets of sets. So l2 should be list not set.here is the code to make list of sets.

    l1 = set(map(int, input('Enter first set: ').split()))
    print(l1)
    n = int(input('Enter n: '))
    l2 = list()
    for i in range(n):
        l2.append(set(set(map(int, input(f'Enter {i + 2}rd set: ').split()))))
    
    print(l2)
    
    # [{1,2,3,4,5},{100,11,12}]
    

3 Comments

I'll try that out now and let you know
I appreciate your solution, but it gives me a set with consolidated elements of the sets i give in input. I have attached a clarification on my post. Please feel free to address any doubts you still have.
Blue You're correct about the part where illogical and mathematically wrong to make a set of sets. But with frozenset() I was able to. I appreciate your elegant solution and will refer the same, since I will always run into a case to make a list of sets.
0
inn = input("enter the number of elements in set")
set1 = set()
for i in range(int(inn)):
    print (i)
    in1 = input("enterset elements:")
    set1.add(in1)
print (set1)

1 Comment

Hope this is very simple set to construct in runtime

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.