0Knowledge
0Knowledge

Reputation: 755

How to print 1 to many items from a 2D list in python

I have a 2D list object fps containing 4 items and the length of the object is 2006 (2006 rows and each row contains 4 elements). The Object looks like

['0012', 'CCN[C@H]1CN', <rdkit.Chem.rdchem.Mol object at 0x7fea177a0260>, <rdkit.DataStructs.cDataStructs.ExplicitBitVect object at 0x7fea0f2fd030>]
['0015', 'CCN[H@H]1CN', <rdkit.Chem.rdchem.Mol object at 0x7fea177a0260>, <rdkit.DataStructs.cDataStructs.ExplicitBitVect object at 0x7fea0f2fd030>]
  ... so on

I want to print only the 4th items. So my code is

for n in range(len(fps)-1): 
  print(fps[n][3])

Output looks like

<rdkit.DataStructs.cDataStructs.ExplicitBitVect object at 0x7fcfa09f3170>
<rdkit.DataStructs.cDataStructs.ExplicitBitVect object at 0x7fcfa09f31c0>
<rdkit.DataStructs.cDataStructs.ExplicitBitVect object at 0x7fcfa09f3210>

Now I want to print all 4th elements as 1 to many relation types. More specifically, fps[n][3] will be printed with all rest of the 2005 elements (only 4th column) and so on. So I wrote this

for n in range(len(fps)-1): 
  print(fps[n][3], fps[n+1:][3]) #Can I use for mapping

But, my code is fine for the first print but giving an error for the second one. The 2nd one giving the whole 2d list. Output looks like

    <rdkit.DataStructs.cDataStructs.ExplicitBitVect object at 0x7fde5df8f300> ['00299', 'Nc1nc(=O)c2ncn(CCC(CO)CO)c2[nH]1', <rdkit.Chem.rdchem.Mol object at 0x7fde5dfde530>, <rdkit.DataStructs.cDataStructs.ExplicitBitVect object at 0x7fde5df8f440>]
<rdkit.DataStructs.cDataStructs.ExplicitBitVect object at 0x7fcfa09f34e0> ['15617', 'OC[C@H](O)[C@@H](O)[C@H](O)[C@H](O)CO[C@H]1O[C@H](CO[C@H]2O[C@H](CO)[C@@H](O)[C@H](O)[C@H]2O)[C@@H](O)[C@H](O)[C@H]1O.[Fe+3]', <rdkit.Chem.rdchem.Mol object at 0x7fcfa0a455d0>, <rdkit.DataStructs.cDataStructs.ExplicitBitVect object at 0x7fcfa09f3620>]

My expected output is like

<rdkit.DataStructs.cDataStructs.ExplicitBitVect object at 0x7fcfa09f3170> <rdkit.DataStructs.cDataStructs.ExplicitBitVect object at 0x7fcfa09f31c0>
<rdkit.DataStructs.cDataStructs.ExplicitBitVect object at 0x7fcfa09f3170> <rdkit.DataStructs.cDataStructs.ExplicitBitVect object at 0x7fcfa09f3210>  

For a more general way my expected output

element_1 element_2
element_1 element_3 
element_1 element_4
........
element_1 element_2006
element_2 element_1
element_2 element_3

......

Is it possible to print in this way?

Upvotes: 0

Views: 143

Answers (2)

Rivers
Rivers

Reputation: 1923

If what you want is such that for this list:

fps = [[0,0,0,1], [0,0,0,2], [0,0,0,3], [0,0,0,4]]

your expected output should be this:

1 2
1 3
1 4
----------
2 1
2 3
2 4
----------
3 1
3 2
3 4
----------
4 1
4 2
4 3
----------

So you can do this:

fps = [[0,0,0,1], [0,0,0,2], [0,0,0,3], [0,0,0,4]]

for index_i,i in enumerate(fps): 
    one_fourth_item = i[3]
    for index_j,j in enumerate(fps):
        many_fourth_item = j[3]
        if index_i != index_j:
            print(one_fourth_item, many_fourth_item)
            
    print("----------")

I'll try to explain the problem with the code you called "2nd one" in your question (fps[n+1:][3]):

First, let simplify it as fps[n:][3]

The part fps[n:] wil return a slice of the source list.

So:

for n == 0 : [[0, 0, 0, 1], [0, 0, 0, 2], [0, 0, 0, 3], [0, 0, 0, 4]]

for n == 1 : [[0, 0, 0, 2], [0, 0, 0, 3], [0, 0, 0, 4]]

for n == 2 : [[0, 0, 0, 3], [0, 0, 0, 4]]

for n == 3 : [[0, 0, 0, 4]]

The part [3] will return the third element of the slice (from fps[n:])

So, for n == 0, fps[n:][3] equals to : [[0, 0, 0, 1], [0, 0, 0, 2], [0, 0, 0, 3], [0, 0, 0, 4]][3], and that is [0,0,0,4]

The problem is that for n == 1 (in this example), the last index is 2, and so you get IndexError: list index out of range

So there is at least these 2 problems in your code : with fps[n:][3] you don't select the "4th item" of the sub-list, but the "4th item" of the source list, and when "n" is greater than the last index you get IndexError: list index out of range.

And for the +1 part in fps[n+1:][3], perhaps you incremented n because you wanted to skip the "one" element, in order to avoid printing "element_1 element_1" or "element_2 element_2" ?

Upvotes: 0

Purujit Kulshreshtha
Purujit Kulshreshtha

Reputation: 39

The code "print(fps[n][3], fps[n+1:][3])" will first print element at index [3] of the sublist of element [n[ of the main/parent list. But after that, it'll print the remaining parent list as the code says "[n+1:]". The semicolon tells the program to take the list from element n+1 till the end. Instead, try running a nested loop to print a 1-many relation, something like:

for one in fps:
    for many in fps:
        print(one[3], many[3])

The outer loop will take an element from the main list and pass it to the inner loop. The inner loop will keep the initial element passed from the outer loop and take each element from the main loop and print the third element of both until each element is done. Then, the outer loop will pass the next element to the inner loop and so on.

Upvotes: 1

Related Questions