Suppose, I have list called C.
C = (1,2,3),(4,5,6),(20),(14),(16,17,18,21),(21,22),(22,23),(24,25)
I would like to join values such as 20 and 14 into a new_list
; only if 20, and 14 do not
occur in any of the subsets such as (1,2,3),(16,17,18,21), etc. I wouldn't want to join (21,22) because (21) already exists in (16,17,18,21). Neither would I want to join (21, 22) or (22,23) because they repeat.
In short, I'm taking (24, 25) & (20) & (14) because they don't repeat in any of the subsets. Also, they must have less than 3 elements.
Example
new_list = (24,25,20,14)
This is what I tried so far.
new_list=[];
for a in range(0, len(C)):
#suppose to prevent out of range error
if a <= len(C) -1:
#suppose to check every subset for repeating elements
for b in range(len(C[a+1])):
#again to prevent out of range error
if b <= len(C) - 1:
#using set comparison (this may be a semantic bug)
false_or_true_trip_wire = set(str(C[a])) <= set(C[b])
#I don't want to accidently append a duplicate
I_do_not_want_both_sets_too_equal = set(str(C[a])) != set(C[b])
if false_or_true_trip_wire == 'False':
if I_do_not_want_both_sets_too_equal == 'True':
new_list.append(C[a])
new_list.append(C[b])
Output
Type errors when any of the subsets have one element. It would work for subsets with 2 or more elements such as one's with len() of 3. Such as (1,2,3)
Example of one of the things I'm trying to do.
C = (5,6,2),(1,3,4),(4),(3,6,2)
for j in range(0, len(C)):
print(len(C[j]))
Output from example
3
3
Traceback (most recent call last):
File "C:/Users/User/Desktop/come on.py", line 4, in <module>
print(len(C[j]))
TypeError: object of type 'int' has no len()
So, is there any way to create a function that would do what I exemplified above? And, without using str()?
Please do give an explanation for someone who hasn't taken a class in Python, but has been self-teaching.
If I can find a function to get rid of all these nested loops it would make it so much easier to get rid of semantic bugs that cause type errors. Any answer would help.
Suppose, I have list called C.
C = (1,2,3),(4,5,6),(20),(14),(16,17,18,21),(21,22),(22,23),(24,25)
First of all, your C
variable is assigned to a tuple
of tuple
and int
objects not a list
. See this tutorial for more info on these objects. You can also verify this is the case with your own code here.
Type errors when any of the subsets have one element. It would work for subsets with 2 or more elements such as one's with len() of 3. Such as (1,2,3)
You get TypeError
because a tuple
of a single object is not actually a tuple
, it is just that object inside of it. Thus if you call len
function on the nested object then the len
function will raise
such a TypeError
should that nested object not be a sequence object with a __len__
method.
int
objects do not have this __len__
method and thus a TypeError: object of type 'int' has no len()
is raised when they are passed into the len
function. In the tuple
you have assigned to C
, you have two such int
objects at index 2 (20)
and 3 (14)
. To actually make these into tuple
objects, you need to use a trailing comma to make what's called a singleton:
C = (1,2,3),(4,5,6),(20,),(14,),(16,17,18,21),(21,22),(22,23),(24,25)
for j in range(0, len(C)):
# Now that every object in the tuple is another tuple len(C[j]) will work!
print(len(C[j]))
print(type(C[j]))
Now that is out of the way, I don't want to assume you want to change C
from a tuple
of tuple
and int
objects into just a tuple
of tuple
objects, so lets go back to your original C = (1,2,3),(4,5,6),(20),(14),(16,17,18,21),(21,22),(22,23),(24,25)
and see if we can write some code that produces something like your expected (24,25,20,14)
following the rules you outlined:
In short, I'm taking (24, 25) & (20) & (14) because they don't repeat in any of the subsets. Also, they must have less than 3 elements.
Here is the code I came up with that seems to follow those rules:
C = (1,2,3),(4,5,6),(20),(14),(16,17,18,21),(21,22),(22,23),(24,25)
temp_C = [x if type(x) == tuple else tuple([x]) for x in C]
new_c = []
for i,c in enumerate(temp_C):
l = len(c)
if l <= 2:
temp_b = [
item for j, sub in enumerate(temp_C) for item in sub if i!=j
]
if all(
[y not in temp_b for y in c]
):
[new_c.append(y) for y in c]
new_c = tuple(new_c)
print(new_c)
outputs:
(20, 14, 24, 25)
It's not the same order as (24,25,20,14)
, but it's as close to your expected output as I'm going to get for you tonight. Finally, here is that code in python tutor. Hopefully, it's logic will become more clear to you as you step through it.