I would like some tips to understand a partiton code - python-3.x

I was doing some code from a MIT course and I got this code as a help function, but there are some parts that are a lil obscure from my python
understanding.
def partitions(set_):
if not set_:
yield []
return
for i in range(2**len(set_)//2):
parts = [set(), set()]
for item in set_:
parts[i&1].add(item)
i >>= 1
for b in partitions(parts[1]):
yield [parts[0]]+b
I undrstand that it make lots of different combinations of a list, a dict or other iterating obj.
I got my eyes rolling about this parts:
parts[i&1].add(item)
i >>= 1
Some of the fellows here could try to explain to me this part?
I look for some in the net, but not sure if I understand completly.
Thanks in advance!
PS- There are any way to make a more readble and using biult in functions like permutations, combinations?

Related

how to get a zig zag pattern between two array?

I am trying to find the zig zag pattern between two arrays. I've come across posts where 1 array is used. I understand the logic of it but even when i append the two lists together, I am unable to get the desired output.
arr1 = [1,2,3,4,5]
arr2 = [6,7,8,9,10]
expected_output = [5,9,3,7,1,6,2,8,4,10]
any hint to solve it would help. P.S I am still learning programming, so if i missed an obvious pattern, do let me know. thanks!

Making the number of executions of a for-loop depending on a variable

As you probably already figured by my question, I am pretty new to programming which is why this question is so basic. But I couldn't really find a question that had an answer to my problem so I thought I might just ask. I have a list that contains integers that I wanted to compare to each other so they can be sorted from highest to lowest. Now for that I wanted to use a for-loop that is executed exactly as many times as there are integers in my list. How do I do that? I tried:
for len(a): # (a is my list)
*code*
Thought it is returning me an error, saying that it couldn't be assigned to the function call. I am not sure why :/ . I hope you can help me.
for i in range(len(a)):
is the usual way; the official Python tutorial is a good place to start for understanding range(), and the fact that the loop is executed as many times as there are elements in your list when you first entered the loop

Simple Syntax Question (tuple conversion)

I'm currently researching different ways to combine, organize and manipulate data for different purposes.
Just today I found this zip() / iter() technique of creating a LIST containing TUPLES while also being able to specify how many elements are in each TUPLE. However, I'm unable to fully understand part of the syntax.
Here is the code:
mylist = [1,2,3,4,5,6]
converted = [x for x in zip(*[iter(mylist)]*2)]
print(converted)
This is the output (which is what I want):
[(1, 2), (3, 4), (5, 6)]
What I'm trying to grasp is the first asterisk. I understand that it's most likely in relation to the '*2' telling the 'iter' or 'zip' function how many elements each tuple should contain, however, I'm trying to grasp the need for it's placement.
Any help is greatly appreciated.
Also, if you know of another technique to accomplish this and feel like sharing, I'd greatly appreciate learning from you.
Thanks again in advance guys!
Basically iter(mylist) makes an iterator object for the list, then it's put into a list [iter(mylist)] which is multiplied by 2 basically making a list that contains two references to the same iterator object: [iter(mylist)]*2 -> [<list_iterator object at 0x7f8fbc1ac610>, <list_iterator object at 0x7f8fbc1ac610>]
The first asterisk unpacks the list as arguments into the zip() function.
To make it easier to understand as I'm not very good at explaining things, this code does the same as yours:
mylist = [1,2,3,4,5,6]
iterators = [iter(mylist)] * 2
converted = [x for x in zip(*iterators)]
print(converted)
So it makes an iterator, then it makes a list that contains two references to the same iterator object by multiplying it by 2.
And then it unpacks the list to be used as arguments for the zip() function
I hope this cleared it up at least a little for you as I'm not very good at explaining.

Should we return and then print the result or just print the result inside the function?

A beginner here.
I have a simple query. Following are two ways of using a cube function(in Python 3.9) to get the desired output.
def cube(x):
return x*x*x
print(cube(5))
or
def cube(x):
print(x*x*x)
cube(5)
both of these blocks will produce 125 as an output, but which one is more preferable according to your own point of view.
Thanks in advance :)
Definitely the top one. When possible functions should be kept as independent as possible, so you can reuse the code in different places, so returning a value is always preferable.
Say for example (very simple example which has other solutions but just to demonstrate) you then wanted to write a function which takes a number to its 6th power. Well, with the bottom example of the cube function you would have to just write out the whole function, but with the top example, you can do this:
def sixth_power(x):
cubed = cube(x)
return cubed * cubed
So hopefully you can see that having the code be reusable is very helpful.

Comprehension with Lists of Dictionaries

I know this isn't exactly the first question about list comprehensions, but I've been looking around and experimenting for a while and can't figure this one out. I'll apologize in advance, I'm a self-taught novice learning from failures.
This is working code, but it screams list comprehension. I understand list comprehensions and use them, but the combination of stacking for and working with the dictionaries within the lists is breaking my brain. How would you simplify this:
results = []
for system in systems: # list of dicts
for result in telnet_results: # list of dicts
if system['master_ip'] == result['master_ip']:
combined = {**system, **result} # merge dicts, right takes precedence
results.append(combined)
Thanks in advance for any help on this.
results = [{**system, **result} for system in systems for result in telnet_results if
system['master_ip'] == result['master_ip']]
Can be also splitted more logically:
results = [{**system, **result}
for system in systems
for result in telnet_results
if system['master_ip'] == result['master_ip']]
Is this "simplified"? I'm not sure. List comprehensions are not magic, and they do not always simplify the code or make it more readable.

Resources