Re: Identical elements
- To: mathgroup at smc.vnet.net
- Subject: [mg88427] Re: Identical elements
- From: tommcd <TCMcDermott at gmail.com>
- Date: Mon, 5 May 2008 06:12:49 -0400 (EDT)
- References: <fvhe2h$3th$1@smc.vnet.net>
On May 3, 11:16 am, KFUPM <hussain.alqaht... at gmail.com> wrote:
> Dear All
>
> I have a list and i need to test whether all the elements in the list
> are identical or no. What is the efficient way to do that? The output
> should be true if all elements are the same and False otherwise. One
> line command is preferred if possible.
>
> Your help is highly appreciated.
>
> Regards,
>
> HMQ
Short answer:
Count[x, x[[1]]] == Length[x] seems efficient,
especially for the case of large lists with most elements equal.
Longer:
As I've only very recently started to use Mathematica for
'programming' I thought I'd try a few different ways :
>From below you can see that count is best, followed by the Do loop
version.
Side note:
Coding the Do loop version was very traumatic for this Fortran
programmer as I've just
learned that Return behaves much differently in a Do loop than in a
For or While loop.
And the behaviour which to me seems more consistent (i.e same as For
and While)
can only be got by using the Return[_,Module] form which is not
documented & I
only discovered by searching this newsgroup. Moreover the current
documentation
(6.02) for return is sparse and doesn't really explain any of this
clearly.
When I do need a loop I prefer Do as it's simple (and close to the
Fortran do loop
in style so easy for quick conversion) and has the advantage that the
looping variables are localized. I know procedural programming is not
encouraged in Mathematica but
sometimes the flow of control is messy & it's not possible to reduce a
block of code
to a small function let alone a one liner.
I'm now not sure how a given Return[] nested in various loops an other
control structures
behaves (other than by testing it by trial and error), and since the
Return[_,Module] is undocumented I guess it's not safe to use. I know
there's Throw/Catch etc. and the real
problem is I expected Return to behave like in Fortran/C, but I think
this does warrant
one or two sentences in the documentation as quite a few programmers
must come to
Mathematica from Fortran &/ C++.
Regards,
Tom McDermott.
In[1]:= f1[x_] :=
Module[{x1 = x[[1]], i, n = Length[x]},
For[i = 2, i <= n, i++, If[x[[i]] != x1, Return[False]]]; True]
In[2]:= f2[x_] :=
Module[{x1 = x[[1]], n = Length[x]},
Do[If[x[[i]] != x1, Return[False, Module]];, {i, 2, n}]; True]
In[3]:= f3[x_] := And @@ (# == x[[1]] & /@ x)
In[4]:= f4[x_] := Module[{x1 = x[[1]]}, And @@ (# == x1 & /@ x)]
In[5]:= f5[
x_] := (Scan[If[# != x[[1]], Return[False]] &, x] === Null)
In[6]:= f6[x_] :=
Module[{x1 = x[[1]]}, (Scan[If[# != x1, Return[False]] &, x] ===
Null)]
In[7]:= f7[x_] := LengthWhile[x, # == x[[1]] &] == Length[x]
In[8]:= f8[x_] := Count[x, x[[1]]] == Length[x]
In[9]:=
t = ConstantArray[0, {9, 7}];
Do[
For[n = 1; i = 1, n < 10^7, n *= 10; i++,
x = ConstantArray[1, {n}];
(*x=RandomInteger[{1,n},n];*)
x[[RandomInteger[{1, n}]]] = 0;
t[[1, i]] += n;
j = 1;
Do[
j++;
t[[j, i]] += Timing[f[x]][[1]];
, {f, {f1, f2, f3, f4, f5, f6, f7, f8}}
]
]
, {k, 10}
]; MatrixForm[t/10]
Out[10]//MatrixForm= \!\(\*
TagBox[
RowBox[{"(", "\[NoBreak]", GridBox[{
{"1", "10", "100", "1000", "10000", "100000", "1000000"},
{"6.083675230250663`*^-16", "5.078402975922103`*^-16",
"7.919012667834124`*^-16", "0.001299800000000279`",
"0.013097899999999621`", "0.11298270000000028`",
"1.1733215999999995`"},
{"6.083675230250663`*^-16", "0.00010000000000050794`",
"7.919012667834124`*^-16", "0.0005999999999994859`",
"0.0074988999999999655`", "0.06299050000000009`",
"0.6567000999999999`"},
{"6.083675230250663`*^-16", "7.409871327634932`*^-16",
"0.0003999000000004959`", "0.00119989999999912`",
"0.01059839999999971`", "0.10818369999999931`",
"1.0992327999999991`"},
{"5.079270337660091`*^-16", "0.00010000000000074099`",
"0.00010000000000089772`", "0.0007998000000010313`",
"0.007098899999999141`", "0.07198899999999954`",
"0.7474868000000006`"},
{"5.079270337660091`*^-16", "7.919012667834124`*^-16",
"0.0001999000000005075`", "0.0007998000000009498`",
"0.007598899999999501`", "0.06838960000000004`",
"0.7099917000000004`"},
{"5.079270337660091`*^-16", "7.919012667834124`*^-16",
"5.845991008987528`*^-16", "0.0006000000000008052`",
"0.006199100000000433`", "0.05239210000000059`",
"0.5442175999999997`"},
{"0.00010000000000050794`", "0.00010000000000047177`",
"0.0001000000000005846`", "0.00149979999999977`",
"0.01489779999999977`", "0.12608060000000074`",
"1.2976026000000003`"},
{"5.078402975922103`*^-16", "7.919012667834124`*^-16",
"5.845096542195228`*^-16", "4.1227871810933796`*^-16",
"0.000699799999999542`", "0.00899880000000006`",
"0.09288559999999928`"}
},
GridBoxAlignment->{
"Columns" -> {{Left}}, "ColumnsIndexed" -> {},
"Rows" -> {{Baseline}}, "RowsIndexed" -> {}},
GridBoxSpacings->{"Columns" -> {
Offset[0.27999999999999997`], {
Offset[0.7]},
Offset[0.27999999999999997`]}, "ColumnsIndexed" -> {}, "Rows" -> {
Offset[0.2], {
Offset[0.4]},
Offset[0.2]}, "RowsIndexed" -> {}}], "\[NoBreak]", ")"}],
Function[BoxForm`e$,
MatrixForm[BoxForm`e$]]]\)
Side note: (maybe some gure can comment on this gripe)...
Coding the Do loop version was very traumatic for this Fortran
programmer as I've just
learned that Return behaves much differently in a Do loop than in a
For or While loop.
And the behaviour which to me seems more consistent (i.e same as For
and While)
can only be got by using the Return[_,Module] form which is not
documented & I
only discovered by searching this newsgroup. Moreover the current
documentation
(6.02) for return is sparse and doesn't really explain any of this
clearly.
When I do need a loop I prefer Do as it's simple (and close to the
Fortran do loop
in style so easy for quick conversion) and has the advantage that the
looping variables are localized. I know procedural programming is not
encouraged in Mathematica but
sometimes the flow of control is messy & it's not possible to reduce a
block of code
to a small function let alone a one liner.
I'm now not sure how a given Return[] nested in various loops an other
control structures
behaves (other than by testing it by trial and error), and since the
Return[_,Module] is undocumented I guess it's not safe to use. I know
there's Throw/Catch etc. and the real
problem is I expected Return to behave like in Fortran/C, but I think
this does warrant
one or two sentences in the documentation as quite a few programmers
must come to
Mathematica from Fortran &/ C++.