Why does building a set fail when using set(int)? - python

I can do
>>> s = {1}
>>> type(s)
<class 'set'>
but
>>> s = set(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
What is the difference?

The difference is that the set() constructor takes an iterable. A single number is not an iterable.
s = set((1,))

Related

How to use struct.unpack to extract int from list of bytes in python 3?

Assuming, I have a list bites with constant length
>>> chunk = [b'\xd0', b'\x00', b'\xd5', b'\x00', b'\xdf', b'\x00', b'\xaa', b'U']
>>> print(type(chunk))
<class 'list'>
>>> print(chunk)
[b'\xd0', b'\x00', b'\xd5', b'\x00', b'\xdf', b'\x00', b'\xaa', b'U']
And I want to get a single int from it, which could be done this way:
>>> a = int.from_bytes(chunk[2], byteorder='little')
>>> b = int.from_bytes(chunk[3], byteorder='little')
>>> decoded = a * 256 + b
>>> print(decoded)
213
How do I use struct.unpack for that purpose?
Several ways I failed:
>>> print(struct.unpack('<xxHxxxx', chunk))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: a bytes-like object is required, not 'list'
>>> tmp = bytes(chunk)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'bytes' object cannot be interpreted as an integer
>>> tmp = bytes([chunk])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object cannot be interpreted as an integer
>>> tmp = bytearray(chunk)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'bytes' object cannot be interpreted as an integer
The initial motivation was to check if struct.unpack is any faster then already working code. But now I want to figure out the right way to use it.
Oh, and if there is any more efficient way, I would be glad to know that too!
The issue is in how you convert a list of bytes to bytes. You can do this with b''.join(list) and then apply your struct unpack.
Example:
>>> import struct
# your list of bytes
>>> lst = [b'\xd0', b'\x00', b'\xd5', b'\x00', b'\xdf', b'\x00', b'\xaa', b'U']
# Convert into `bytes`
>>> bts = b''.join(lst)
# Unpack
>>> print(struct.unpack('<xxHxxxx', bts))
(213,)
Note that you can also unpack the returned tuple with:
>>> (a,) = struct.unpack('<xxHxxxx', bts)
>>> a
213

what to do if in python we get valueERRor

I have tried this statement
N,T,M = list(map(int,input().split()))
and python is showing me
N,T,M = list(map(int,input().split()))
ValueError: not enough values to unpack (expected 3, got 1)
What to do?
It seems you're receiving this error because you are trying to assign three distinct values (N, T, and M) even though your list only has one value:
By running this in the Python3 terminal, we see the same error you reported:
>>>N,T,M=list([1])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: not enough values to unpack (expected 3, got 1)
With 2 items in the list, the error message changes:
>>> N,T,M=list([1, 2])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: not enough values to unpack (expected 3, got 2)
If you have 3 items in your list, Python will assign one item to each of your variables:
>>>N,T,M=list([1, 2, 3])
# This works and no error is received
Then, with 4 items in the list, Python complains:
>>> N,T,M=list([1, 2, 3, 4])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 3)
Essentially, you need to ensure that the number of items on the right side of your expression will be three in order to instantiate three separate variables.

Python list.__iadd__ will take a str as argument

I just by accident found this out:
>>> l = []
>>> l + 'a'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "str") to list
>>> l += 'a'
>>> l
['a']
>>> l + 'abcd'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "str") to list
>>> l += 'abcd'
>>> l
['a', 'a', 'b', 'c', 'd']
Is this expected behaviour? I can't find an explanation for this anywhere, and it seems really weird to me
Now testing further...
>>> l += 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
This led me to believe that str only works because it is an iterable, so I tried:
>>> class Test:
... l = [1, 2, 3]
...
... def __iter__(self):
... for i in self.l:
... yield i
...
>>> l += Test()
>>> l
['a', 'a', 'b', 'c', 'd', 1, 2, 3]
>>> l + Test()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "Test") to list
Now this seems pretty weird and not very pythonic, I was wondering if this might be a bug, any thoughts?

Editing every element in the array to return an array of edited(sliced) elements

Hi I am trying to make edits to every element in the array to return an array of edited(sliced) elements. However, I am getting the error below. Any help is appreciated.
Traceback
>>> p=Playlist.objects.get(id=3)
>>> l=p.song.values_list('link', flat=True)
>>> print(l)
<QuerySet ['https://www.youtube.com/watch?v=_DqmVMlJzqA', 'https://www.youtube.com/watch?v=_DqmVMlJzqA', 'https://www.youtube.com/watch?v=_DqmVMlJzqA', 'https://www.youtube.com/watch?v=k6PiQr-lQY4', 'https://www.youtube.com/watch?v=gqOEoUR5RHg']>
>>> print([l[i][17:] if l[i][0:17] == 'https://youtu.be/' else l[i][32:] for i in l])
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "<console>", line 1, in <listcomp>
File "C:\Users\hanya\AppData\Local\Programs\Python\Python37\lib\site-packages\django\db\models\query.py", line 278, in __getitem__
raise TypeError
TypeError

Why do set operations work with iterables only when using methods?

Why do set operations work with arbitrary iterables when using set methods, but not operators? To show what I mean:
>>> {0, 1, 2, 3}.intersection([0, 1])
{0, 1}
>>> {0, 1, 2, 3} & [0, 1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for &: 'set' and 'list'
>>>
>>> {0, 1, 2, 3}.union([4, 5])
{0, 1, 2, 3, 4, 5}
>>> {0, 1, 2, 3} | [4, 5]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'set' and 'list'
From the docs:
Note, the non-operator versions of union(), intersection(), difference(), and symmetric_difference(), issubset(), and issuperset() methods will accept any iterable as an argument. In contrast, their operator based counterparts require their arguments to be sets. This precludes error-prone constructions like set('abc') & 'cbs' in favor of the more readable set('abc').intersection('cbs').
It was considered less error-prone this way.

Categories

Resources