6

I have a list: {0, 1, 1, 1, 2, 2, 2, 6}. I want to replace all the elements that are greater than 1 with the integer 1. In other words, I want Mma to return the list {0,1,1,1,1,1,1,1,1}.

geoffrey
  • 867
  • 4
  • 6

5 Answers5

7

Usual approach would be to use ReplaceAll:

list = {0, 1, 1, 1, 2, 2, 2, 6};
list/.{x_?(# > 1 &) -> 1}

A slick approach would be

Boole /@ GreaterEqualThan[1] /@ list

Or even

Map[Min[#, 1] &, list]

Faster approach would be to use:

Unitize[list]
Clip[list]

All of them would give you:

{0, 1, 1, 1, 1, 1, 1, 1}

I just ran list = Table[RandomInteger[10], 100000] and used Mr.Wizard's timeAvg function:

list /. {x_?(# > 1 &) -> 1} // timeAvg
Boole /@ GreaterEqualThan[1] /@ list // timeAvg
Map[Min[#, 1] &, l] // timeAvg
Unitize[l] // timeAvg
Clip[l] // timeAvg

0.0690836

0.0559747

0.00204779

0.000139352

0.00022492

exp ikx
  • 768
  • 3
  • 13
4

I just googled "wolfram mathematica replace if". Based on the first link I was able to figure it out in a minute!

lst = {0, 1, 1, 1, 2, 2, 2, 6};
lst /. {x_?(# > 1 &) -> 1}
{0, 1, 1, 1, 1, 1, 1, 1}
Toorop
  • 160
  • 5
1
list = {0, 1, 1, 1, 2, 2, 2, 6};

1.

Using SequenceReplace (new in 11.3)

SequenceReplace[list, {Except @ 0} -> 1]

{0, 1, 1, 1, 1, 1, 1, 1}

2.

Some position-based solutions

p = Position[list, x_ /; x > 1]

{{5}, {6}, {7}, {8}}

MapAt[1 &, p] @ list;

ReplaceAt[_ :> 1, p] @ list;

ReplacePart[p -> 1] @ list;

All return

{0, 1, 1, 1, 1, 1, 1, 1}

eldo
  • 67,911
  • 5
  • 60
  • 168
1
lst = {0, 1, 1, 1, 2, 2, 2, 6};

Using SubsetMap:

p = Position[lst, n_ /; n > 1];

SubsetMap[Subtract @@ {#, #} + 1 &, #, p] &@lst

Result:

{0, 1, 1, 1, 1, 1, 1, 1}

Or using Cases:

Cases[lst, n_ :> If[n > 1, 1, n]]

Result:

{0, 1, 1, 1, 1, 1, 1, 1}

E. Chan-López
  • 23,117
  • 3
  • 21
  • 44
1

This is a long comment which wouldn't fit in the provided space, so here it goes. The conclusion is that good test data results in more general and compliant solutions.

-- TLDR

OP requires: to replace all the elements that are greater than 1 with the integer 1.

It is almost implied that list members are natural numbers and the answers conform to the provided data.


The documentation states that Unitize:

gives 0 when x is zero, and 1 when x has any other numerical value.

Hence in this context, negative numbers are also converted to 1 which is not desired. Also, a non-numerical value would remain unevaluated.


For a list that has elements with other Heads and Signs, a possible solution could be:

lst = {0, 1, 1.1, -2, 2, 2, 0.9, 6, a, 3 + 4 I, 1/2, 17/3};

Clear[g] g[n_Real | n_Rational | n_Integer] := Clip[n, {-∞, 1}, {n, 1}] g[n_] := n

{lst, Cases[lst, n_ :> g[n]]} // Grid


enter image description here

Syed
  • 52,495
  • 4
  • 30
  • 85