• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC SKILL
  3. decrease list of lists by 1 hierarchy list

Stats

  • Locked Locked
  • Replies 7
  • Subscribers 143
  • Views 14585
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

decrease list of lists by 1 hierarchy list

Leonardo Vinci
Leonardo Vinci over 7 years ago

i have a list named A in this format:    (  (((x1) (y1))) (((x2)(y2))) (((x3)(y3)))  )

But i have to decrease its listing hierarchy by 1, ie. i want a format like this: ( ((x1)(y1)) ((x2)(y2)) ((x3)(y3)) )

How can i do this? 

Thanks,

Leonardo da Vinci 
 

  • Cancel
  • Andrew Beckett
    Andrew Beckett over 7 years ago

    You can do this (destructively) by doing:

    A=foreach(mapcan sublist A sublist)

    You can do it non-destructively (if each sublist only has a single element) by doing:

    foreach(mapcar sublist A car(sublist))

    Regards,

    Andrew.

    • Cancel
    • Vote Up +1 Vote Down
    • Cancel
  • RK56
    RK56 over 7 years ago in reply to Andrew Beckett

    Andrew,

    Could you please explain your mapcan solution?  I find mapcar easy to implement but mapcan is some how tougher to understand.

    -Ramakrishnan

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 7 years ago in reply to RK56

    Ramakrishnan,

    There is a class of functions in SKILL called mapping functions, which iterate over a list (or multiple lists). These can either be used this way:

    mappingFunction(existingFunctionAcceptingNargs list1 ... listN)

    Or if the function doesn't exist already, you could create an anonymous function:

    mappingFunction(lambda((arg1 ... argN) ... do something ...) list1 ... listN)

    However, many people are put off by using lambda, so there's a convenience form using foreach:

    foreach(mappingFunction arg list ... code that uses arg ...)

    or for multiple lists:

    foreach(mappingFunction (arg1 ... argN) list1 ... listN ... code that uses arg1 through argN ...)

    Let me start by describing the 6 main mapping functions. The lists used in the examples are:

    l1='(1 2 3 4 5 6)
    l2='(4 3 9 1 7 8)

    Function name Input to existing function Return value Example Return value from example What is printed (if anything)
    mapc each element in turn first original list mapc('println l1) (1 2 3 4 5 6) 1
    2
    3
    4
    5
    6
    map remainder of each list in turn first original list map('println l1) (1 2 3 4 5 6) (1 2 3 4 5 6)
    (2 3 4 5 6)
    (3 4 5 6)
    (4 5 6)
    (5 6)
    (6)
    mapcar each element in turn list of the return values of the function called mapcar('plus l1 l2) (5 5 12 5 12 14)
    maplist remainder of each list in turn list of the return values of the function called maplist('length l1) (6 5 4 3 2 1)
    mapcan each element in turn

    function called needs to return a list; these are all appended
    (efficiently) and returned

    mapcan('list l1 l1) (1 1 2 2 3 3 4
    4 5 5 6 6
    )
    mapcon remainder of each list in turn function called needs to return a list; these are all appended
    (efficiently) and returned
    mapcon('list l1 l2) ((1 2 3 4 5 6)
    (4 3 9 1 7 8)
    (2 3 4 5 6)
    (3 9 1 7 8)
    (3 4 5 6)
    (9 1 7 8)
    (4 5 6)
    (1 7 8)
    (5 6)
    (7 8)
    (6)
    (8)
    )

    Some of the examples above are a bit artificial, but hopefully you get the idea.

    In this case, we have our input list A='(  (((x1) (y1))) (((x2)(y2))) (((x3)(y3)))  ). When we do:

    A=foreach(mapcan sublist A
        println(sublist)
        sublist
      )

    it will print out:

    (((x1) (y1)))
    (((x2) (y2)))
    (((x3) (y3)))

    The return value will be these lists all appended together (as I said, it does this destructively, so it is much more efficient than using append):

    (((x1) (y1)) ((x2) (y2)) ((x3) (y3)))

    By the way, this foreach(mapcan...) example is completely equivalent to:

    A=mapcan(
        lambda((sublist) println(sublist) sublist)
        A
      )

    You can see other examples of using foreach(mapcan ...) using l1 defined above:

    foreach(mapcan elem l1 when(evenp(elem) list(elem**2)))

    This will then append the following lists:

    nil (4) nil (16) nil (36) 

    and so return:

    (4 16 36)

    In other words, a list of the squares of the even members of the list.

    Hope that helps?

    Regards,

    Andrew.

    • Cancel
    • Vote Up +1 Vote Down
    • Cancel
  • Leonardo Vinci
    Leonardo Vinci over 7 years ago in reply to Andrew Beckett

    Thanks Andrew! :) 

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • RK56
    RK56 over 7 years ago in reply to Andrew Beckett

    Thanks very much Andrew.  This is awesome. Few questions here

    1. How does mapcan skip the nil while appending in the example of list of squares of even numbers? A regular append function does not skip the nils

    2. I see mapcar and mapcan can be used alternatively, Is there any situation where only one of them is the right candidate?

    -Ramakrishnan

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 7 years ago in reply to RK56

    Ramakrishnan,

    1. append() does "skip" the nils. If you do: append('(1 2 3 4) nil) or append(nil '(1 2 3 4)) then both return (1 2 3 4). What mapcan uses is really closer to nconc() rather than append (because it's destructive - in other words it doesn't copy the second list, and alters the final pointer in the first list to point to the first element of the second), but either way that does affect the useful ability of mapcon to add nothing to the return list if you don't want to.
    2. They are not the same any way. mapcar generates a 1 to 1 list (1 value in the resulting list for each original value in the input list), whereas mapcan generates a 1 to many (including 0) mapping. They can be equivalent in the case where the return value of each operation is a list with a single element - e.g. foreach(mapcar n '(1 2 3 4) n**2) is equivalent to foreach(mapcan n '(1 2 3 4) list(n**2)) but that's not only more verbose but I suspect it's less efficient (I didn't check). So in the case where they are equivalent, mapcar is the right candidate; in any other case, they're not interchangeable, so whichever gives the functionality you want is the right candidate!

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • RK56
    RK56 over 7 years ago in reply to Andrew Beckett

    Andrew,

    Understood. Nil is an empty list though it does not appear visually so.  Visually  it looks like an atom.

    append('(1 2 nil 3) '(7 8 9)) will give '(1, 2, nil, 3, 7, 8, 9) but

    append('(1 2 nil 3) nil) will give '(1, 2, nil, 3)

    -Ramakrishnan

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information