to explain how to get between all of the other answers, we start with a tidied up (and fixed) version of the OPs original code:
def edges2cordinate(edges):
num_entries = len(edges[0])
res = set()
for i in range(0, num_entries):
res.add((edges[0][i], edges[1][i]))
return res
the first cleanup happens after noticing that range()
allows a single argument to be passed, causing it to count from zero up to that argument. we also notice that num_entries
is only used once, so we can move it to where it's used, giing us:
def edges2cordinate(edges):
res = set()
for i in range(len(edges[0])):
res.add((edges[0][i], edges[1][i]))
return res
second, notice that we keep getting the first and second elements of edges
on every iteration of the for
loop. Python gives us "assignment expressions" (PEP 572) which lets us write this as:
def edges2cordinate(edges):
first_arr, second_arr = edges
res = set()
for i in range(len(first)):
res.add((first_arr[i], second_arr[i]))
return res
and should be a bit faster, because we only need to get the items out once rather than every loop iteration.
every answer has pointed to using zip()
to make this code more concise. you use zip
by giving it multiple things that can be iterated over, like list
s or your arrays, and it zips them giving you back tuples containing items from the things you gave it. e.g:
list(zip([1,2,3], [4,5,6]))
evaluates to [(1,4), (2,5), (3,6)]
. the reason for the list()
surrounding it is that (in Python 3) zip
gives you back an iterator, and passing this iterator to list()
gives you a list containing items from that iterator.
third, the smallest change to use zip
on the above code would be:
def edges2cordinate(edges):
first_arr, second_arr = edges
res = set()
for first_item_i, second_item_i in zip(first_arr, second_arr):
res.add((first_item_i, second_item_i))
return res
further, we're using these "assignment expressions" to redundantly take things apart and put them together, so we can rewrite this to:
def edges2cordinate(edges):
res = set()
for pair_i in zip(edges[0], edges[1]):
res.add(pair_i)
return res
we can also change to using zip(*edges)
which "unpacks" edges
into the arguments to zip
, i.e. edges[0]
goes to the first parameter of zip
, edges[1]
goes to the second parameter, etc.
another tool Python gives you are generator expressions, which lets us turn lots of this into one line:
def edges2cordinate(edges):
return set(pair_i for pair_i in zip(*edges))
but we aren't "doing anything" with this generator expression, so it can be removed, getting to the minimalist:
def edges2cordinate(edges):
return set(zip(*edges))
in a follow-up comment, you asked how to reverse the order of the edges. one way would be to do:
def edges2cordinate(edges):
return set(zip(edges[1], edges[0]))
which will hopefully do the obvious thing. the suggested reversed()
function probably does what you'd expect, but can be used as:
def edges2cordinate(edges):
return set(zip(*reversed(edges)))
to keep it minimal