简体   繁体   中英

What is the equivalent of the following Python list comprehension in Fortran?

I am trying to write the following list comprehension(written in Python) in Fortran.

lit = [[x,y] for x in [p,q,r] for y in [h,k,l] if [x,y]!=[a,b]]

where a, b, p ,q ,r, h, k, l are integers

How can I achieve it if I want to fill columns first in 2D Fortran array?

The Python code returns a list. It is equivalent to

for x in [p,q,r]:
     for y in [h,k,l]:
         if [x,y]!=[a,b]:
             list.append([x,y])

I made two sublists in Fortran. sublist_x and sublist_y where each list contains p,q,r and h,k,l respectively.

integer :: list(0:7), sublist_x(0:2),sublist_y(0:2), count
 count =-1

do i=0,7
   if (i%3 ==0)
   count = count +1
   endif
   list(0,i)=sublist_x(i%3)
   list(1,i)=sublist_y(count%3)
enddo

I think this is a complex way of doing things...

If I understand correctly you want the cartesian product of the two little lists, excluding the element [a,b] ? If I misunderstand, stop reading now. Here's a little program that almost does what you want ...

PROGRAM test

  IMPLICIT NONE

  INTEGER, DIMENSION(:), ALLOCATABLE :: listx, listy, bad_element
  INTEGER, DIMENSION(:,:), ALLOCATABLE :: outlist
  INTEGER :: ix, jx, alstat, n_elements

  LOGICAL, DIMENSION(:), ALLOCATABLE :: rows

  listx = [1,2,3]
  listy = [21,22,23]
  bad_element = [3,21]

  n_elements = SIZE(listx)*SIZE(listy)
  ALLOCATE(outlist(2,n_elements),stat=alstat)
  IF (alstat/=0) THEN
     WRITE(*,*) "something went wrong allocating the result array"
     STOP
  ELSE
     outlist(1,:) = RESHAPE(listx,[n_elements],listx)
     outlist(2,:) = RESHAPE(SPREAD(listy,1,SIZE(listx)),[n_elements])
  END IF

  DO ix = 1, n_elements
     IF (ALL(outlist(:,ix)==bad_element)) THEN
        outlist(:,ix:) = EOSHIFT(outlist(:,ix:),1,dim=2)
     END IF
  END DO

END PROGRAM TEST

At the end of this program outlist contains the cartesian product with any elements equal to the bad element replaced by 0 s and pushed to the end of outlets . For the hard-wired numbers above, the output is:

    1    2    1    2    3    1    2    3    0
   21   21   22   22   22   23   23   23    0

I guess you shouldn't have too much difficulty trimming this to remove the 0 s, nor in packaging this program into a routine. And I hope the code explains itself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM